Issues (1752)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class/sms.php (9 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * @package		fwolflib
4
 * @subpackage	class
5
 * @copyright	Copyright © 2010, Fwolf
6
 * @author		Fwolf <[email protected]>
7
 * @since		2010-11-23
8
 */
9
10
11
require_once(dirname(__FILE__) . '/fwolflib.php');
12
require_once(FWOLFLIB . 'func/uuid.php');
13
14
15
/**
16
 * SMS treat and send.
17
 *
18
 * Using gammu daemon to send sms.
19
 *
20
 * @deprecated  Use Fwlib\Net\Sms\SmsSender
21
 * @package		fwolflib
22
 * @subpackage	class
23
 * @copyright	Copyright © 2010, Fwolf
24
 * @author		Fwolf <[email protected]>
25
 * @since		2010-11-23
26
 */
27
class Sms extends Fwolflib {
0 ignored issues
show
Deprecated Code introduced by
The class Fwolflib has been deprecated with message: Use classes in Fwlib namespace, see PSR-0/1/2

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
28
29
	/**
30
	 * Db object to connect sms stat db
31
	 * @var	object
32
	 */
33
	protected $oDb = null;
34
35
36
	/**
37
	 * construct
38
	 *
39
	 * @param	object	$o_db
40
	 */
41
	public function __construct ($o_db = null) {
42
		parent::__construct();
43
44
		if (!is_null($o_db))
45
			$this->oDb = &$o_db;
46
	} // end of class __construct
47
48
49
	/**
50
	 * Count sms will split to N part to send
51
	 *
52
	 * If only ascii chars include, 140 chars for 1 sms part,
53
	 * if has chinese chars, 70 chars for 1 sms part only.
54
	 *
55
	 * 1 chinese char will count as 1 char.
56
	 *
57
	 * @param	string	$s_sms
58
	 * @return	integer
59
	 */
60
	public function CountPart ($s_sms = '') {
61
		// Is there chinese in sms ?
62 View Code Duplication
		if (mb_strlen($s_sms, 'utf-8') == strlen($s_sms)) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
63
			// No chinese, 140 chars per part
64
			return (ceil(strlen($s_sms) / 140));
65
		}
66
		else {
67
			// Convert chinese char to ascii, for count
68
			return (ceil(mb_strlen($s_sms, 'utf-8') / 70));
69
		}
70
	} // end of func CountPart
71
72
73
	/**
74
	 * Parse dest/phone number string.
75
	 *
76
	 * Do:
77
	 * 	Split phone number.
78
	 * 	Format phone number.
79
	 * 	Remove duplicate number.
80
	 *
81
	 * @param	mixed	$s_dest
82
	 * @return	array
83
	 */
84
	public function DestParse ($s_dest) {
85
		// If array given, still need convert to string
86
		// to format and validate phone number.
87
		if (is_array($s_dest))
88
			$s_dest = implode(',', $s_dest);
89
90
		// Replace all special chars to ','
91
		$s_dest = str_replace(',', ',', $s_dest);
92
		$s_dest = preg_replace('/[ ,;\r\n\t]{1,}/'
93
			, ',', $s_dest);
94
		$ar_dest = explode(',', $s_dest);
95
96
		// Remove +86, 0086
97
		foreach ($ar_dest as &$dest) {
98
			if ('+86' == substr($dest, 0, 3))
99
				$dest = substr($dest, 3);
100
			elseif ('0086' == substr($dest, 0, 4))
101
				$dest = substr($dest, 4);
102
		}
103
104
		// Remove duplicate
105
		$ar = array();
106
		foreach ($ar_dest as &$dest) {
107
			// Invalid length
108
			if (11 != strlen($dest) && '10' != substr($dest, 0, 2))
109
				continue;
110
111
			if (false == in_array($dest, $ar))
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
112
				$ar[] = $dest;
113
		}
114
115
		return $ar;
116
	} // end of func DestParse
117
118
119
	/**
120
	 * Write sent sms stat information.
121
	 *
122
	 * @param	array	$ar_dest
123
	 * @param	string	$s_sms
124
	 * @param	integer	$i_cat
125
	 */
126
	protected function DestStatSet ($ar_dest, $s_sms, $i_cat) {
127
		if (is_null($this->oDb)) {
128
			$this->Log('No db connection.', 5);
129
			return;
130
		}
131
132
		// Gen data array
133
		$ar_data = array();
134
		$ar_data['uuid']	= Uuid();
0 ignored issues
show
Deprecated Code introduced by
The function Uuid() has been deprecated with message: Use Fwlib\Util\Uuid::gen()

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
135
		$ar_data['st']		= date('Y-m-d H:i:s');
136
		$ar_data['cat']		= $i_cat;
137
		$ar_data['cnt']		= count($ar_dest);
138
		$ar_data['cnt_cm']	= 0;
139
		$ar_data['cnt_cu']	= 0;
140
		$ar_data['cnt_ct']	= 0;
141
		$ar_data['dest']	= implode(',', $ar_dest);
142
		$ar_data['cnt_part']= $this->CountPart($s_sms);
143
		$ar_data['sms']		= $s_sms;
144
145
		// Which company's number ?
146
		$ar_cm = array(134, 135, 136, 137, 138, 139, 147
147
			, 150, 151, 152, 157, 158, 159, 187, 188);
148
		$ar_cu = array(130, 131, 132, 155, 156, 185, 186);
149
		$ar_ct = array(133, 153, 180, 189);
150 View Code Duplication
		foreach ($ar_dest as $dest) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
151
			$i = intval(substr($dest, 0, 3));
152
			if (in_array($i, $ar_cm))
153
				$ar_data['cnt_cm'] ++;
154
			elseif (in_array($i, $ar_cu))
155
				$ar_data['cnt_cu'] ++;
156
			elseif (in_array($i, $ar_ct))
157
				$ar_data['cnt_ct'] ++;
158
		}
159
160
		// Save to db
161
		$this->oDb->Write('sms_stat', $ar_data, 'I');
162
	} // end of func DestStatSet
163
164
165
	/**
166
	 * Detect and set path of gammu smsd inject cmd
167
	 *
168
	 * @param	$s_path		Manual additional path
169
	 * @return	string
170
	 */
171
	public function GetPathGammuSmsdInject ($s_path = '') {
172
		$ar_path = $this->aCfg['path_bin'];
173
174
		if (!empty($s_path)) {
175
			// Add to array
176
			array_unshift($ar_path, $s_path);
177
		}
178
179
		// Find a usable path
180
		$b_found = false;
181 View Code Duplication
		while (!$b_found && !empty($ar_path)) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
182
			$s_cmd = $ar_path[0] . 'gammu-smsd-inject';
183
			if (is_executable($s_cmd)) {
184
				$b_found = true;
185
				break;
186
			}
187
			array_shift($ar_path);
188
		}
189
		if ($b_found) {
190
			$this->Log('Got gammu smsd inject execute file: '
191
				. $s_cmd, 1);
0 ignored issues
show
The variable $s_cmd does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
192
			$this->aCfg['path_gammu_smsd_inject'] = $s_cmd;
193
		}
194
		else {
195
			$this->Log('Can\' find gammu smsd inject execute file.', 5);
196
			exit();
197
		}
198
199
		return $this->aCfg['path_gammu_smsd_inject'];
200
	} // end of func GetPathGammuSmsdInject
201
202
203
	/**
204
	 * Init config vars, give default value.
205
	 *
206
	 * @return	this
207
	 */
208
	public function Init () {
209
		parent::Init();
210
211
		// Possible bin path
212
		$this->aCfg['path_bin'] = array(
213
			'/usr/bin/',
214
			'/usr/local/bin/',
215
			'/bin/',
216
		);
217
218
		// Path of gammu-smsd-inject
219
		$this->aCfg['path_gammu_smsd_inject'] = '';
220
221
		// Cmd template of gammu-smsd-inject cmd
222
		$this->aCfg['cmd_gammu_smsd_inject']
223
			= '[cmd] TEXT [dest] -autolen 600 -report -validity MAX -unicode -textutf8 "[sms]"';
224
225
		return $this;
226
	} // end of func Init
227
228
229
	/**
230
	 * Send sms using gammu smsd inject method.
231
	 *
232
	 * Notice: On webserver, need assign www-data to gammu group,
233
	 * 	and make /var/log/gammu-smsd.log g+w .
234
	 * 	Modem server need not, only conn to db is required.
235
	 *
236
	 * @param	mixed	$ar_dest	Dest phone number array
237
	 * 								or string split by ' ,;,\r\n'.
238
	 * @param	string	$s_sms		Msg to send.
239
	 * @param	integer	$i_cat		Category of sms, for stat.
240
	 * @return	integer				Actual valid phone number sent.
241
	 */
242
	public function SendUsingGammuSmsdInject ($ar_dest, $s_sms, $i_cat = 0) {
243
		if (empty($this->aCfg['path_gammu_smsd_inject']))
244
			$this->GetPathGammuSmsdInject();
245
246
		$ar_dest = $this->DestParse($ar_dest);
247
		if (1 > count($ar_dest)) {
248
			$this->Log('No valid number to sent.', 4);
249
			return 0;
250
		}
251
		$this->DestStatSet($ar_dest, $s_sms, $i_cat);
252
253
		// Prepare sms to sent
254
		$s_sms = str_replace(array('[cmd]', '[sms]')
255
			, array($this->aCfg['path_gammu_smsd_inject'], $s_sms)
256
			, $this->aCfg['cmd_gammu_smsd_inject']);
257
		$i = strpos($s_sms, '[dest]');
258
		if (1 > $i) {
259
			$this->Log('Something wrong with gammu smsd inject cmd template'
260
				, 5);
261
			exit();
262
		}
263
		$s_sms1 = substr($s_sms, 0, $i);
264
		$s_sms2 = substr($s_sms, $i + 6);	// 6 is length of '[dest]'
265
266
		// Loop to sent
267
		foreach ($ar_dest as $dest) {
268
			$s_cmd = $s_sms1 . $dest . $s_sms2;
269
			//exec($s_cmd);
270
			$ar_output = array();
271
			$i_return = 0;
272
			exec($s_cmd, $ar_output, $i_return);
273
			if (0 != $i_return) {
0 ignored issues
show
It seems like you are loosely comparing $i_return of type integer|null to 0; this is ambiguous as not only 0 == 0 is true, but null == 0 is true, too. Consider using a strict comparison ===.
Loading history...
274
				// Error occur
275
				$this->Log('Gammu inject error: ' . $ar_output[1], 5);
276
				return 0;
277
			}
278
		}
279
280
		return count($ar_dest);
281
	} // end of func SendUsingGammuSmsdInject
282
283
284
} // end of class Sms
285
286
287
/*
288
--
289
-- stat table
290
--
291
CREATE TABLE sms_stat (
292
	uuid				CHAR(36)			NOT NULL,
293
	-- Sent time
294
	st					DATETIME			NOT NULL,
295
	-- Cat of msg
296
	cat					INTEGER				NOT NULL DEFAULT 0,
297
	-- Total dest number count
298
	cnt					INTEGER				NOT NULL DEFAULT 0,
299
	-- Count of China Mobile
300
	cnt_cm				INTEGER				NOT NULL DEFAULT 0,
301
	-- Count of China Unicom
302
	cnt_cu				INTEGER				NOT NULL DEFAULT 0,
303
	-- Count of China Telecom
304
	cnt_ct				INTEGER				NOT NULL DEFAULT 0,
305
	-- Dest phone numbers
306
	dest				TEXT				NOT NULL,
307
	-- Will sms split to N part to send
308
	cnt_part			INTEGER				NOT NULL DEFAULT 0,
309
	-- Msg
310
	sms					TEXT				NOT NULL,
311
	ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
312
	PRIMARY KEY (uuid),
313
	INDEX idx_sms_stat_1 (st)
314
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
315
*/
316
?>
0 ignored issues
show
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
317