Additional modules for fraud protection

From ISPWiki

Jump to: navigation, search

BILLmanager allows you to add custom module handlers. The fraud system module structure contains two files:

  1. The XML file that describes the interface called billmgr_mod_xxx.xml, (where xxx is random symbol) that is used how to set up connection parameters. The file should locate in the {path to installation folder}/etc/ directory and should be encoded in the UTF-8 character set.
  2. The binary or test file (depending the language) of a module handler. The file should locate in the /usr/local/ispmgr/sbin/ directory, and its name should start with fp.

Contents

XML file structure

An XML consists of two parts:

  • Description of the parameter form
  • Localized fields
<?xml version="1.0" encoding="UTF-8"?>
<mgrdata>
	<metadata name="fraudparam_xxx" type="form"><!--Fraud protection form settings-->
		<form>
			<field name="field_1">
				<input type="text" name="field_1" empty="no"/>
			</field>
			<!--...-->
			<field name="field_n">
				<input type="text" name="field_n" empty="no"/>
			</field>
		</form>
	</metadata>
	<metadata name="smsgateparam_xxx" type="form"><!--SMS gateway form settings-->
		<form>
			<field name="field_1">
				<input type="text" name="field_1" empty="no"/>
			</field>
			<!--...-->
			<field name="field_n">
				<input type="text" name="field_n" empty="no"/>
			</field>
		</form>
	</metadata>
	<lang name="en">
		<messages name="fraudconf"><!--Name of the gateway in the fraud protection module in English -->
			<msg name="xxx">XXX</msg>
		</messages>
		<messages name="supportgate.stepsms.selectgate"><!--Name of the SMS gateway in English-->
			<msg name="xxx">XXX</msg>
		</messages>
		<messages name="fraudparam_xxx"><!--Names of the fraud protection settings in English-->
			<msg name="title">Phone check from XXX/msg>
			<msg name="field_1">Field 1</msg>
			<msg name="hint_field_1">Hint for Field 1</msg>
			<!--...-->
			<msg name="field_n">Field n</msg>
			<msg name="hint_field_n">Hint for Field n</msg>
			<!--General messages. They are used in all the modules-->
			<msg name="phonereg">Phone number filter</msg>
			<msg name="hint_phonereg">Provide the phone numbers that will be allowed for use. Leaving the field blank will not set the filter.</msg>
			<msg name="template">Message template (en)</msg>
			<msg name="hint_template">Provide a message template. The code is specified in the %CODE% parameter or at the end of the message if the parameter is omitted.</msg>
			<msg name="msg_error_phonereg_regex">Invalid regular expression</msg>
		</messages>
		<messages name="smsgateparam_xxx"><!--Names of the SMS gateway settings in English-->
			<msg name="title">SMS gate from Text Magic</msg>
			<msg name="field_1">Field 1</msg>
			<msg name="hint_field_1">Hint for Field 1</msg>
			<!--...-->
			<msg name="field_n">Field n</msg>
			<msg name="hint_field_n">Hint for Field n</msg>
			<!--General messaged. They are used in all the modules-->
			<msg name="phonereg">Phone filter</msg>
			<msg name="hint_phonereg">Enter a filter for phone numbers that can be used or leave the field blank</msg>
			<msg name="send_from">Time</msg>
			<msg name="hint_send_from">Provide a default time in the format: HH:MM:SS</msg>
			<msg name="send_to">To</msg>
			<msg name="hint_send_to">Provide a default time in the format: HH:MM:SS</msg>
		</messages>
	</lang>
	<lang name="ru">
		<messages name="fraudconf"><!--Name of the gateway for fraud protection in Russian-->
			<msg name="xxx">XXX</msg>
		</messages>
		<messages name="supportgate.stepsms.selectgate"><!--Name of the SMS gateway in Russian-->
			<msg name="xxx">XXX</msg>
		</messages>
		<messages name="fraudparam_xxx"><!--Names of the fraud protection settings in Russian-->
			<msg name="title">Phone verification from XXX</msg>
			<msg name="field_1">Field 1</msg>
			<msg name="hint_field_1">Hint for Field 1</msg>
			<!--...-->
			<msg name="field_n">Field n</msg>
			<msg name="hint_field_n">Hint for Field n</msg>
			<!--General messagesя. They are used in all the modules-->
			<msg name="phonereg">Phone number filters</msg>
			<msg name="hint_phonereg">Provide the phone numbers that will be allowed for u. You may leave this field blank</msg>
			<msg name="template">Message template (en)</msg>
			<msg name="hint_template">Enter a message template. You ma leave this field blank. The code will be sent to the %CODE% or at the end of the message, if the parameter is omittedн.</msg>
			<msg name="msg_error_phonereg_regex">Invalid regular expression</msg>
		</messages>
		<messages name="smsgateparam_xxx"><!--Name of the SMS gateway settings in Russian-->
			<msg name="title">SMS gateway from Text Magic</msg>
			<msg name="field_1">Field 1</msg>
			<msg name="hint_field_1">Hint for Field 1</msg>
			<!--...-->
			<msg name="field_n">Field n</msg>
			<msg name="hint_field_n">Hint for Field n</msg>
			<!--General messages. They are used in all the messages-->
			<msg name="phonereg">Phone number filter</msg>
			<msg name="hint_phonereg">Provide the phone numbers that will be allowed for u. You may leave this field blank</msg>
			<msg name="send_from">Start time с</msg>
			<msg name="hint_send_from">Enter the default sending time in the format: HH:ММ:SS</msg>
			<msg name="send_to">End time</msg>
			<msg name="hint_send_to">Enter the default sending time in the format: HH:ММ:SS</msg>
		</messages>
	</lang>
</mgrdata>


Where xxx is the name of the handler's file without ftp. All parameters in the module edit form will be saved in the file (for fraud protection) or database (for an SMS gateway).

Module structure

BILLmanager passes the data to a module file via the command line parameters.

The handler module must process the command line parameters and respond to the commands.

The module configuration parameters are located in the '{path to installation folder}/etc/fpxxx.conf (sgxxx{partner ID}.conf - to set up an SMS gateway), where xxx is a module name in the format: <parameter name> <value>. Each parameter is specified in a separate line.

Received parameters and commands

  • features - a list of supported features should be passed to STDIN: fraud and/orgate, for example: "fraud gate".
  • validate - check the data and pass 'ok' to STDOUT.
  • tune - if necessary, pass the XML document describing the interface to STDOUT.
  • type - pass a module type: 'sms', if an SMS is to be sent, or 'call', if a call is to be made.
  • senderparamname - specify the name of the parameter to be kept in the gateway configuration. Add the field's description into the xml of this parameter.
  • senderbyproject - if the gateway enables to use different sender's names, you may return 'yes'. Therefore, the gateway edit form will include several fields for a sender's name.
  • call - call the handler to send an SMS or make a call. The full version looks like this 'fpxxx call ccode phone code lang', where call is a master command, ccode is a country code in the phone number (the first line received when verifying a phone number), phone is a phone number, code is a verification code, lang is a default user language.
  • sendsms - the command to pass an SMS; possible parameters: partnerid' phone' and a message text, where 'partnerid' is a partner account's identifier, if an sms is sent to a partner's client; 'phone' is a phone number to which the sms should be sent.
  • If completed successfully, call the command '{path to installation folder}/sbin/mgrctl -m billmgr -o xml longtask.finish elid=(PID of startup file) status=ok'. Once the sms has been successfully sent, pass "OK" to STDOUT, otherwise send "ERROR".
  • If not, call the command '{path to installation folder}/sbin/mgrctl -m billmgr -o xml longtask.finish elid=(PID of the startup file) status=err errmsg=(text of the error message)'

More information can be found in the article LongTask

Example

Consider creating a module script for connecting to API TextMagic (the XML text given below is only an example, you must replace it with valid parameters).

XML document

The XML document:

<?xml version="1.0" encoding="UTF-8"?>
<mgrdata>
	<metadata name="fraudparam_textmagic" type="form">
		<form>

Following are the module configuration parameters: <field name="username">

				<input type="text" name="username" empty="no"/>
			</field>
			<field name="password">
				<input type="text" name="password" empty="no"/>
			</field>
			<field name="phonereg">
				<input type="text" name="phonereg"/>
			</field>
		</form>
	</metadata>
	<metadata name="smsgateparam_textmagic" type="form">
		<form>

Following are the sms gateway configuration parameters:

			<field name="username">
				<input type="text" name="username" empty="no"/>
			</field>
			<field name="password">
				<input type="text" name="password" empty="no"/>
			</field>
		</form>
	</metadata>

Example in English:

	<lang name="en">
		<messages name="fraudconf">
			<msg name="textmagic">Text Magic</msg>
		</messages>

		<messages name="fraudparam_textmagic">
			<msg name="title">Phone check from Text Magic</msg>
			<msg name="username">User name</msg>
			<msg name="hint_username">Specify a user name</msg>
			<msg name="password">Password</msg>
			<msg name="hint_password">Specify a password</msg>
			<msg name="phonereg">Phone filter</msg>
			<msg name="hint_phonereg">Specify a phone filter. This field can be empty.</msg>
		</messages>
		<messages name="smsgateparam_textmagic">
			<msg name="title">SMS gate from Text Magic</msg>
			<msg name="username">User name</msg>
			<msg name="hint_username">Specify a user name</msg>
			<msg name="password">Password</msg>
			<msg name="hint_password">Specify a password</msg>
		</messages>
	</lang>

Example in Russian:

	<lang name="ru">
		<messages name="fraudconf">
			<msg name="textmagic">Text Magic</msg>
		</messages>

		<messages name="fraudparam_textmagic">
			<msg name="title">Проверка телефона от Text Magic</msg>
			<msg name="username">Имя пользователя</msg>
			<msg name="hint_username">Укажите имя пользователя</msg>
			<msg name="password">Пароль</msg>
			<msg name="hint_password">Укажите пароль</msg>
			<msg name="phonereg">Фильтр номеров</msg>
			<msg name="hint_phonereg">Укажите фильтр разрешенных номеров телефонов. Поле можно оставить пустым</msg>
		</messages>
		<messages name="smsgateparam_textmagic">
			<msg name="title">СМС шлюз от Text Magic</msg>
			<msg name="username">Имя пользователя</msg>
			<msg name="hint_username">Укажите имя пользователя</msg>
			<msg name="password">Пароль</msg>
			<msg name="hint_password">Укажите пароль</msg>
		</messages>
	</lang>
</mgrdata>

Script handler

Script handler written in PHP

#!/usr/bin/php
<?php

Install the exceptions' handler, open the log file to specify the parameters from the command line

	set_error_handler("tmErrorHandler");
	$log_file = fopen("/usr/local/ispmgr/var/fptextmagic.log", "a");
	fwrite($log_file, "=======".date("M j H:i:s") . "[] " ."=======\n");
	foreach($argv as $line_num => $line) {
		fwrite($log_file, date("M j H:i:s") . "[] " . $line_num.":".$line."\n");
	}

If few parameters were received, output the usage information

	if ($argc<2) {
		usage();
	} else {
		switch($argv[1]) {

Output a list of features:

			case "features":
				echo "fraud gate";
				break;

Check parameters

			case "validate":
				echo "ok";
				break;

Configure the form

			case "tune":
				break;

Return a type of the gateway

			case "type":
				echo "sms";
				break;

Process the SMS for fraud protection

			case "call":
				if ($argc<5 || $argc>6) {
					fwrite($log_file, date("M j H:i:s") . "[] " . "Invalid params number." . "\n");

					usage();
				} else {
					fwrite($log_file, date("M j H:i:s") . "[] " . "Start call API." . "\n");

					if ($argc == 4) {
						callfraud($argv[2] . $argv[3], $argv[4]);
					} else {
						callfraud($argv[2] . $argv[3], $argv[4], $argv[5]);
					}
				}
				break;

Process the SMS

			case "sendsms":
				if ($argc > 4 || $argc < 3) {
					fwrite($log_file, date("M j H:i:s") . "[] " . "Invalid params number." . "\n");

					usage();
				} else {
					fwrite($log_file, date("M j H:i:s") . "[] " . "Start call API." . "\n");
					$msg = ""
					$f = fopen('php://stdin', 'r');
					while ($line = fgets($f))
						$msg .= $line;
					callgate($argv[2], $argv[3], $msg);
				}
				break;

Process the password recovery code

			case "sendcode":
				if ($argc < 6) {
					fwrite($log_file, date("M j H:i:s") . "[] " . "Invalid params number." . "\n");

					usage();
				} else {
					fwrite($log_file, date("M j H:i:s") . "[] " . "Start call API." . "\n");
					$msg = $argv[4];
					callgate($argv[5], $argv[1], $msg);
					exec("/usr/local/ispmgr/sbin/mgrctl -m billmgr -o xml longtask.finish elid=". getenv("MGR_LT_PID") ." status=ok");
				}
				break;
			default:
				usage();
		}	
	}

	fwrite($log_file, "=======".date("M j H:i:s") . "[] " ."=======\n");
	fclose($log_file);

This function is used to display the usage information

function usage() {
		print("ISPsystem BILLmanager plugin v1.0
Text Magic integration plugin.
Usage:
	features - print 'fraud gate';
	validate - print 'ok';
	tune - no return value;
	type - return 'sms' as type of plugin;
	sendsms 'partnerid' 'phone_number' <msg> - send sms to phone number;
 	call 'country_code' 'phone_number' 'verification_code' 'lang' - execute plugin function.\n");
}

This function is used to send SMS for fraud protection

function callfraud($phone, $code, $lang = "en") {
		global $log_file;

		fwrite($log_file, date("M j H:i:s") . "[] " . "Phone: " . $phone . " Code: " . $code . "\n");

		$msg = "Your verification code is ".$code;

Get parameters from the configuration file

		$lines = file("/usr/local/ispmgr/etc/fptextmagic.php.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);

		$params = array();

		foreach ($lines as $line_num => $line) {
			$arr_key = "";
			$arr_val = "";
			list($arr_key, $arr_val) = explode(" ", $line, 2);
			$params += array($arr_key => $arr_val);
		}

		$curl_client = curl_init("https://www.textmagic.com/app/api");

		fwrite($log_file, date("M j H:i:s") . "[] " . curl_error($curl_client) . "\n");
		$data = array("username" => $params["username"], "password" => $params["password"], "cmd" => "send",
			      "text" => $msg, "phone" => $phone, "unicode" => "0");

		curl_setopt($curl_client, CURLOPT_SSL_VERIFYPEER, 0);

		fwrite($log_file, date("M j H:i:s") . "[] " . curl_error($curl_client) . "\n");

		curl_setopt($curl_client, CURLOPT_POST, 1);

		fwrite($log_file, date("M j H:i:s") . "[] " . curl_error($curl_client) . "\n");

		curl_setopt($curl_client, CURLOPT_POSTFIELDS, $data);
		fwrite($log_file, date("M j H:i:s") . "[] " . print_r($data, true) . "\n");
		curl_setopt($curl_client, CURLOPT_RETURNTRANSFER, true);

		fwrite($log_file, date("M j H:i:s") . "[] " . curl_error($curl_client) . "\n");

		$output = curl_exec($curl_client);

		fwrite($log_file, date("M j H:i:s") . "[] " . curl_error($curl_client) . "\n");

		fwrite($log_file, date("M j H:i:s") . "[] " . $output . "\n");
		
		fwrite($log_file, date("M j H:i:s") . "[] Finish task with PID file " . getenv("MGR_LT_PID") . "\n");

		exec("/usr/local/ispmgr/sbin/mgrctl -m billmgr -o xml longtask.finish elid=". getenv("MGR_LT_PID") ." status=ok");

		curl_close($curl_client);

This function is used to send messages as an SMS gateway and to send a password recovery password)

	function callgate($partnerid, $phone, $msg) {
		global $log_file;

		fwrite($log_file, date("M j H:i:s") . "[] " . "PartnerID: " . $partnerid . " Phone: " . $phone . "\n");

Get parameters from the database

		$params = array();

		$param_array = file("/usr/local/ispmgr/etc/billmgr.conf", FILE_SKIP_EMPTY_LINES	);
						
		$params["DBHost"] = "localhost";
		$params["DBName"] = "billmgr";
		$params["DBUser"] = "root";
		$params["DBPassword"] = "";
			
		foreach ($param_array as $param_line_num => $param_line) {
			$param_array = preg_split("/\s+/", $param_line);
			$params[$param_array[0]] = count($param_array) > 1 ? $param_array[1] : "";
		}
			
		$conn = mysql_connect($params["DBHost"], $params["DBUser"], $params["DBPassword"]);
		$res = mysql_select_db($params["DBName"], $conn);
		if (!$res)
			throw Exception("Database connection problem!");

		if ($partnerid == 0)
			$partnerid = 1;

		$query = "select xmldata from support_gate sg left join project p on p.id = sg.project where p.account = $partnerid and gatetype = 1 and xmldata like '%textmagic.php%'";

		$result = mysql_query($query, $conn);
		if (!$result)
			throw new Exception("MySql error: ".mysql_error($conn));
		$row = mysql_fetch_row($result);

		$xmldata = new SimpleXMLElement($row[0]);
		$params["username"] = $xmldata->username;
		$params["password"] = $xmldata->password;

		$curl_client = curl_init("https://www.textmagic.com/app/api");

		fwrite($log_file, date("M j H:i:s") . "[] " . curl_error($curl_client) . "\n");

		$data = array("username" => $params["username"], "password" => $params["password"], "cmd" => "send",
			      "text" => $msg, "phone" => $phone, "unicode" => "0");

		curl_setopt($curl_client, CURLOPT_SSL_VERIFYPEER, 0);

		fwrite($log_file, date("M j H:i:s") . "[] " . curl_error($curl_client) . "\n");

		curl_setopt($curl_client, CURLOPT_POST, 1);

		fwrite($log_file, date("M j H:i:s") . "[] " . curl_error($curl_client) . "\n");

		curl_setopt($curl_client, CURLOPT_POSTFIELDS, $data);
		fwrite($log_file, date("M j H:i:s") . "[] " . print_r($data, true) . "\n");
		curl_setopt($curl_client, CURLOPT_RETURNTRANSFER, true);

		fwrite($log_file, date("M j H:i:s") . "[] " . curl_error($curl_client) . "\n");

		$output = curl_exec($curl_client);

		fwrite($log_file, date("M j H:i:s") . "[] " . curl_error($curl_client) . "\n");

		fwrite($log_file, date("M j H:i:s") . "[] " . $output . "\n");

		curl_close($curl_client);
		echo "OK";
	}

Error handler

	function tmErrorHandler($errno, $errstr, $errfile, $errline) {
		global $log_file;
		fwrite($log_file, date("M j H:i:s") . "[] " . "Error [" . $errno . "] ErrMsg: " . $errstr . ". In file: " . $errfile . ". In line: " . $errline . "\n");
	    return true;
	}
?>


Troubleshooting

The script cannot start from BILLmanager or this attempt fails as everything runs ok in the console.

The most probable cause of this issue is that BILLmanager (in some versions) does not reset the LD_LIBRARY_PATH environment variable prior to starting the module.

To resolve this issue you can create an executable file that will reset that environment variable and start the module you need. You need to perform the following operations:

  1. Rename the module's file by removing 'fp' from the beginning.
  1. create an sh script and name it 'fpxxx', where xxx is a module name.
  1. In the sh script locate the code that will reset the environmental variable and start the module.

Example:

  1. !/bin/sh

unset LD_LIBRARY_PATH

exec /usr/local/ispmgr/sbin/textmagic $*

Was this helpful? Yes | No
Personal tools