1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Fritz!Box API - A simple wrapper for automated changes in the Fritz!Box Web-UI |
4
|
|
|
* |
5
|
|
|
* handles the new secured login/session system and implements a cURL wrapper |
6
|
|
|
* new in v0.2: Can handle remote config mode via https://example.dyndns.org |
7
|
|
|
* new in v0.3: New method doGetRequest handles GET-requests |
8
|
|
|
* new in v0.4: Added support for the new .lua forms like the WLAN guest access settings |
9
|
|
|
* new in v0.5: added support for the new .lua-loginpage in newest Fritz!OS firmwares and refactored the code |
10
|
|
|
* |
11
|
|
|
* @author Gregor Nathanael Meyer <Gregor [at] der-meyer.de> |
12
|
|
|
* @license http://creativecommons.org/licenses/by-sa/3.0/de/ Creative Commons cc-by-sa |
13
|
|
|
* @version 0.5.0b7 2013-01-02 |
14
|
|
|
* @package Fritz!Box PHP tools |
15
|
|
|
*/ |
16
|
|
|
|
17
|
|
|
/* A simple usage example |
|
|
|
|
18
|
|
|
* |
19
|
|
|
* try |
20
|
|
|
* { |
21
|
|
|
* // load the fritzbox_api class |
22
|
|
|
* require_once('fritzbox_api.class.php'); |
23
|
|
|
* $fritz = new fritzbox_api(); |
24
|
|
|
* |
25
|
|
|
* // init the output message |
26
|
|
|
* $message = date('Y-m-d H:i') . ' '; |
27
|
|
|
* |
28
|
|
|
* // update the setting |
29
|
|
|
* $formfields = array( |
30
|
|
|
* 'telcfg:command/Dial' => '**610', |
31
|
|
|
* ); |
32
|
|
|
* $fritz->doPostForm($formfields); |
33
|
|
|
* $message .= 'Phone ' . $dial . ' ringed.'; |
34
|
|
|
* } |
35
|
|
|
* catch (Exception $e) |
36
|
|
|
* { |
37
|
|
|
* $message .= $e->getMessage(); |
38
|
|
|
* } |
39
|
|
|
* |
40
|
|
|
* // log the result |
41
|
|
|
* $fritz->logMessage($message); |
42
|
|
|
* $fritz = null; // destroy the object to log out |
43
|
|
|
*/ |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* the main Fritz!Box API class |
47
|
|
|
* |
48
|
|
|
*/ |
49
|
|
|
class fritzbox_api { |
50
|
|
|
/** |
51
|
|
|
* @var object config object |
52
|
|
|
*/ |
53
|
|
|
public $config = array(); |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* @var string the session ID, set by method initSID() after login |
57
|
|
|
*/ |
58
|
|
|
protected $sid = '0000000000000000'; |
59
|
|
|
|
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* the constructor, initializes the object and calls the login method |
63
|
|
|
* |
64
|
|
|
* @access public |
65
|
|
|
*/ |
66
|
|
|
public function __construct($password = false,$user_name = false,$fritzbox_ip = 'fritz.box',$force_local_login = false) |
67
|
|
|
{ |
68
|
|
|
// init the config object |
69
|
|
|
$this->config = new fritzbox_api_config(); |
70
|
|
|
|
71
|
|
|
// try autoloading the config |
72
|
|
|
if (file_exists(__DIR__ . '/fritzbox_user.conf.php') && is_readable(__DIR__ . '/fritzbox_user.conf.php') ) { |
73
|
|
|
require_once(__DIR__ . '/fritzbox_user.conf.php'); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
// set FRITZ!Box-IP and URL |
77
|
|
|
$this->config->setItem('fritzbox_ip',$fritzbox_ip); |
78
|
|
|
|
79
|
|
|
// check if login on local network (fritz.box) or via a dynamic DNS-host |
80
|
|
|
if ($fritzbox_ip != 'fritz.box' && !$force_local_login) { |
81
|
|
|
$this->config->setItem('enable_remote_config',true); |
82
|
|
|
$this->config->setItem('remote_config_user',$user_name); |
83
|
|
|
$this->config->setItem('remote_config_password',$password); |
84
|
|
|
$this->config->setItem('fritzbox_url', 'https://'.$this->config->getItem('fritzbox_ip')); |
85
|
|
|
} else { |
86
|
|
|
$this->config->setItem('enable_remote_config',false); |
87
|
|
|
if($user_name != false){ |
|
|
|
|
88
|
|
|
$this->config->setItem('username',$user_name); |
89
|
|
|
} |
90
|
|
|
if($password != false){ |
|
|
|
|
91
|
|
|
$this->config->setItem('password',$password); |
92
|
|
|
} |
93
|
|
|
$this->config->setItem('fritzbox_url', 'http://' . $this->config->getItem('fritzbox_ip')); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
// make some config consistency checks |
97
|
|
|
if ( $this->config->getItem('enable_remote_config') === true ){ |
98
|
|
|
if ( !$this->config->getItem('remote_config_user') || !$this->config->getItem('remote_config_password') ){ |
99
|
|
|
$this->error('ERROR: Remote config mode enabled, but no username or no password provided'); |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
else { |
103
|
|
|
$this->config->setItem('old_remote_config_user', null); |
104
|
|
|
$this->config->setItem('old_remote_config_password', null); |
105
|
|
|
} |
106
|
|
|
$this->sid = $this->initSID(); |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* the destructor just calls the logout method |
112
|
|
|
* |
113
|
|
|
* @access public |
114
|
|
|
*/ |
115
|
|
|
public function __destruct() |
116
|
|
|
{ |
117
|
|
|
$this->logout(); |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* do a POST request on the box |
123
|
|
|
* the main cURL wrapper handles the command |
124
|
|
|
* |
125
|
|
|
* @param array $formfields an associative array with the POST fields to pass |
126
|
|
|
* @return string the raw HTML code returned by the Fritz!Box |
127
|
|
|
*/ |
128
|
|
|
public function doPostForm($formfields = array()) |
129
|
|
|
{ |
130
|
|
|
$ch = curl_init(); |
131
|
|
|
|
132
|
|
|
if ( isset($formfields['getpage']) && strpos($formfields['getpage'], '.lua') > 0 ) |
133
|
|
|
{ |
134
|
|
|
curl_setopt($ch, CURLOPT_URL, $this->config->getItem('fritzbox_url') . $formfields['getpage'] . '?sid=' . $this->sid); |
135
|
|
|
unset($formfields['getpage']); |
136
|
|
|
} |
137
|
|
|
else |
138
|
|
|
{ |
139
|
|
|
// add the sid, if it is already set |
140
|
|
|
if ($this->sid != '0000000000000000') |
141
|
|
|
{ |
142
|
|
|
$formfields['sid'] = $this->sid; |
143
|
|
|
} |
144
|
|
|
curl_setopt($ch, CURLOPT_URL, $this->config->getItem('fritzbox_url') . '/cgi-bin/webcm'); |
145
|
|
|
} |
146
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
147
|
|
|
curl_setopt($ch, CURLOPT_POST, 1); |
148
|
|
|
if ( $this->config->getItem('enable_remote_config') == true ) |
149
|
|
|
{ |
150
|
|
|
// set name of SSL-certificate (must be same as remote-hostname (dynDNS) of FRITZ!Box) and remove port in address if alternate port is given |
151
|
|
|
if (strpos($this->config->getItem('fritzbox_ip'),":")){ |
152
|
|
|
$ssl_cert_fritzbox = explode(":", $this->config->getItem('fritzbox_ip')); |
153
|
|
|
$ssl_cert_fritzbox = $ssl_cert_fritzbox[0]; |
|
|
|
|
154
|
|
|
} else { |
155
|
|
|
$ssl_cert_fritzbox = $this->config->getItem('fritzbox_ip'); |
|
|
|
|
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
// set SSL-options and path to certificate |
159
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 2); |
160
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); |
161
|
|
|
curl_setopt($ch, CURLOPT_CAPATH, '/etc/ssl/certs'); |
162
|
|
|
|
163
|
|
|
// support for pre FRITZ!OS 5.50 remote config |
164
|
|
View Code Duplication |
if (!$this->config->getItem('use_lua_login_method')){ |
|
|
|
|
165
|
|
|
curl_setopt($ch, CURLOPT_USERPWD, $this->config->getItem('remote_config_user') . ':' . $this->config->getItem('remote_config_password')); |
166
|
|
|
} |
167
|
|
|
} |
168
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($formfields)); |
169
|
|
|
$output = curl_exec($ch); |
170
|
|
|
curl_close($ch); |
171
|
|
|
return $output; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
public function doPostFile($formfields = array(), $filefileds = array()) |
175
|
|
|
{ |
176
|
|
|
$ch = curl_init(); |
177
|
|
|
|
178
|
|
|
// add the sid, if it is already set |
179
|
|
|
if ($this->sid != '0000000000000000') |
180
|
|
|
{ |
181
|
|
|
// 'sid' MUST be the first POST variable!!! (otherwise it will not work!!) |
182
|
|
|
// therfore we use array_merge to ensuere the foreach outputs 'sid' fist |
183
|
|
|
$formfields = array_merge(array('sid' => $this->sid), $formfields); |
184
|
|
|
//$formfields['sid'] = $this->sid; |
|
|
|
|
185
|
|
|
} |
186
|
|
|
curl_setopt($ch, CURLOPT_URL, $this->config->getItem('fritzbox_url') . '/cgi-bin/firmwarecfg'); |
187
|
|
|
curl_setopt($ch, CURLOPT_POST, 1); |
188
|
|
|
|
189
|
|
|
// enable for debugging: |
190
|
|
|
//curl_setopt($ch, CURLOPT_VERBOSE, TRUE); |
|
|
|
|
191
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
192
|
|
|
|
193
|
|
|
// if filefileds not specified ('@/path/to/file.xml;type=text/xml' works fine) |
194
|
|
|
if(empty( $filefileds )) { |
195
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $formfields); // http_build_query |
196
|
|
|
} |
197
|
|
|
// post calculated raw data |
198
|
|
|
else { |
199
|
|
|
$header = $this->_create_custom_file_post_header($formfields, $filefileds); |
200
|
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER , array( |
201
|
|
|
'Content-Type: multipart/form-data; boundary=' . $header['delimiter'], 'Content-Length: ' . strlen($header['data']) ) |
202
|
|
|
); |
203
|
|
|
|
204
|
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $header['data']); |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
$output = curl_exec($ch); |
208
|
|
|
|
209
|
|
|
// curl error |
210
|
|
|
if(curl_errno($ch)) { |
211
|
|
|
$this->error(curl_error($ch)." (".curl_errno($ch).")"); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
// finger out an error message, if given |
215
|
|
|
preg_match('@<p class="ErrorMsg">(.*?)</p>@is', $output, $matches); |
216
|
|
|
if (isset($matches[1])) |
217
|
|
|
{ |
218
|
|
|
$this->error(str_replace(' ', ' ', $matches[1])); |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
curl_close($ch); |
222
|
|
|
return $output; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
private function _create_custom_file_post_header($postFields, $fileFields) { |
226
|
|
|
// form field separator |
227
|
|
|
$delimiter = '-------------' . uniqid(); |
228
|
|
|
|
229
|
|
|
/* |
|
|
|
|
230
|
|
|
// file upload fields: name => array(type=>'mime/type',content=>'raw data') |
231
|
|
|
$fileFields = array( |
232
|
|
|
'file1' => array( |
233
|
|
|
'type' => 'text/xml', |
234
|
|
|
'content' => '...your raw file content goes here...', |
235
|
|
|
'filename' = 'filename.xml' |
236
|
|
|
), |
237
|
|
|
); |
238
|
|
|
// all other fields (not file upload): name => value |
239
|
|
|
$postFields = array( |
240
|
|
|
'otherformfield' => 'content of otherformfield is this text', |
241
|
|
|
); |
242
|
|
|
*/ |
243
|
|
|
|
244
|
|
|
$data = ''; |
245
|
|
|
|
246
|
|
|
// populate normal fields first (simpler) |
247
|
|
|
foreach ($postFields as $name => $content) { |
248
|
|
|
$data .= "--" . $delimiter . "\r\n"; |
249
|
|
|
$data .= 'Content-Disposition: form-data; name="' . urlencode($name) . '"'; |
250
|
|
|
$data .= "\r\n\r\n"; |
251
|
|
|
$data .= $content; |
252
|
|
|
$data .= "\r\n"; |
253
|
|
|
} |
254
|
|
|
// populate file fields |
255
|
|
|
foreach ($fileFields as $name => $file) { |
256
|
|
|
$data .= "--" . $delimiter . "\r\n"; |
257
|
|
|
// "filename" attribute is not essential; server-side scripts may use it |
258
|
|
|
$data .= 'Content-Disposition: form-data; name="' . urlencode($name) . '";' . |
259
|
|
|
' filename="' . $file['filename'] . '"' . "\r\n"; |
260
|
|
|
|
261
|
|
|
//$data .= 'Content-Transfer-Encoding: binary'."\r\n"; |
|
|
|
|
262
|
|
|
// this is, again, informative only; good practice to include though |
263
|
|
|
$data .= 'Content-Type: ' . $file['type'] . "\r\n"; |
264
|
|
|
// this endline must be here to indicate end of headers |
265
|
|
|
$data .= "\r\n"; |
266
|
|
|
// the file itself (note: there's no encoding of any kind) |
267
|
|
|
$data .= $file['content'] . "\r\n"; |
268
|
|
|
} |
269
|
|
|
// last delimiter |
270
|
|
|
$data .= "--" . $delimiter . "--\r\n"; |
271
|
|
|
|
272
|
|
|
return array('delimiter' => $delimiter, 'data' => $data); |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
/** |
276
|
|
|
* do a GET request on the box |
277
|
|
|
* the main cURL wrapper handles the command |
278
|
|
|
* |
279
|
|
|
* @param array $params an associative array with the GET params to pass |
280
|
|
|
* @return string the raw HTML code returned by the Fritz!Box |
281
|
|
|
*/ |
282
|
|
|
public function doGetRequest($params = array()) |
283
|
|
|
{ |
284
|
|
|
// add the sid, if it is already set |
285
|
|
|
if ($this->sid != '0000000000000000') |
286
|
|
|
{ |
287
|
|
|
$params['sid'] = $this->sid; |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
$ch = curl_init(); |
291
|
|
|
if ( strpos($params['getpage'], '.lua') > 0 ) |
292
|
|
|
{ |
293
|
|
|
$getpage = $params['getpage'] . '?'; |
294
|
|
|
unset($params['getpage']); |
295
|
|
|
} |
296
|
|
|
else |
297
|
|
|
{ |
298
|
|
|
$getpage = '/cgi-bin/webcm?'; |
299
|
|
|
} |
300
|
|
|
curl_setopt($ch, CURLOPT_URL, $this->config->getItem('fritzbox_url') . $getpage . http_build_query($params)); |
301
|
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); |
302
|
|
|
curl_setopt($ch, CURLOPT_HTTPGET, 1); |
303
|
|
|
if ( $this->config->getItem('enable_remote_config') ) |
304
|
|
|
{ |
305
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); |
306
|
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); |
307
|
|
|
|
308
|
|
|
// support for pre FRITZ!OS 5.50 remote config |
309
|
|
View Code Duplication |
if ( !$this->config->getItem('use_lua_login_method') ) |
|
|
|
|
310
|
|
|
{ |
311
|
|
|
curl_setopt($ch, CURLOPT_USERPWD, $this->config->getItem('remote_config_user') . ':' . $this->config->getItem('remote_config_password')); |
312
|
|
|
} |
313
|
|
|
} |
314
|
|
|
$output = curl_exec($ch); |
315
|
|
|
curl_close($ch); |
316
|
|
|
return $output; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
|
320
|
|
|
/** |
321
|
|
|
* the login method, handles the secured login-process |
322
|
|
|
* newer firmwares (xx.04.74 and newer) need a challenge-response mechanism to prevent Cross-Site Request Forgery attacks |
323
|
|
|
* see http://www.avm.de/de/Extern/Technical_Note_Session_ID.pdf for details |
324
|
|
|
* |
325
|
|
|
* @return string a valid SID, if the login was successful, otherwise throws an Exception with an error message |
326
|
|
|
*/ |
327
|
|
|
protected function initSID() |
328
|
|
|
{ |
329
|
|
|
// determine, wich login type we have to use |
330
|
|
|
if ( $this->config->getItem('use_lua_login_method') == true ) |
331
|
|
|
{ |
332
|
|
|
$loginpage = '/login_sid.lua'; |
333
|
|
|
} |
334
|
|
|
else |
335
|
|
|
{ |
336
|
|
|
$loginpage = '../html/login_sid.xml'; |
337
|
|
|
} |
338
|
|
|
|
339
|
|
|
// read the current status |
340
|
|
|
$session_status_simplexml = simplexml_load_string($this->doGetRequest(array('getpage' => $loginpage))); |
341
|
|
|
|
342
|
|
View Code Duplication |
if ( !is_object($session_status_simplexml) || get_class($session_status_simplexml) != 'SimpleXMLElement' ) |
|
|
|
|
343
|
|
|
{ |
344
|
|
|
$this->error('Response of initialization call ' . $loginpage . ' in ' . __FUNCTION__ . ' was not xml-formatted.'); |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
// perhaps we already have a SID (i.e. when no password is set) |
348
|
|
|
if ( $session_status_simplexml->SID != '0000000000000000' ) |
349
|
|
|
{ |
350
|
|
|
return $session_status_simplexml->SID; |
351
|
|
|
} |
352
|
|
|
// we have to login and get a new SID |
353
|
|
|
else |
354
|
|
|
{ |
355
|
|
|
// the challenge-response magic, pay attention to the mb_convert_encoding() |
356
|
|
|
$challenge = $session_status_simplexml->Challenge; |
|
|
|
|
357
|
|
|
|
358
|
|
|
// do the login |
359
|
|
|
$formfields = array( |
360
|
|
|
'getpage' => $loginpage, |
361
|
|
|
); |
362
|
|
|
if ( $this->config->getItem('use_lua_login_method') ) |
363
|
|
|
{ |
364
|
|
|
if ( $this->config->getItem('enable_remote_config') ) |
365
|
|
|
{ |
366
|
|
|
$formfields['username'] = $this->config->getItem('remote_config_user'); |
367
|
|
|
$response = $challenge . '-' . md5(mb_convert_encoding($challenge . '-' . $this->config->getItem('remote_config_password'), "UCS-2LE", "UTF-8")); |
368
|
|
|
} |
369
|
|
|
else |
370
|
|
|
{ |
371
|
|
|
if ( $this->config->getItem('username') ) |
372
|
|
|
{ |
373
|
|
|
$formfields['username'] = $this->config->getItem('username'); |
374
|
|
|
} |
375
|
|
|
$response = $challenge . '-' . md5(mb_convert_encoding($challenge . '-' . $this->config->getItem('password'), "UCS-2LE", "UTF-8")); |
376
|
|
|
} |
377
|
|
|
$formfields['response'] = $response; |
378
|
|
|
} |
379
|
|
|
else |
380
|
|
|
{ |
381
|
|
|
$response = $challenge . '-' . md5(mb_convert_encoding($challenge . '-' . $this->config->getItem('password'), "UCS-2LE", "UTF-8")); |
382
|
|
|
$formfields['login:command/response'] = $response; |
383
|
|
|
} |
384
|
|
|
$output = $this->doPostForm($formfields); |
385
|
|
|
|
386
|
|
|
// finger out the SID from the response |
387
|
|
|
$session_status_simplexml = simplexml_load_string($output); |
388
|
|
View Code Duplication |
if ( !is_object($session_status_simplexml) || get_class($session_status_simplexml) != 'SimpleXMLElement' ) |
|
|
|
|
389
|
|
|
{ |
390
|
|
|
$this->error('Response of login call to ' . $loginpage . ' in ' . __FUNCTION__ . ' was not xml-formatted.'); |
391
|
|
|
} |
392
|
|
|
|
393
|
|
|
if ( $session_status_simplexml->SID != '0000000000000000' ) |
394
|
|
|
{ |
395
|
|
|
return (string)$session_status_simplexml->SID; |
396
|
|
|
} |
397
|
|
|
else |
398
|
|
|
{ |
399
|
|
|
$this->error('ERROR: Login failed with an unknown response.'); |
400
|
|
|
} |
401
|
|
|
} |
402
|
|
|
} |
403
|
|
|
|
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* the logout method just sends a logout command to the Fritz!Box |
407
|
|
|
* |
408
|
|
|
*/ |
409
|
|
|
protected function logout() |
410
|
|
|
{ |
411
|
|
|
if ( $this->config->getItem('use_lua_login_method') == true ) |
412
|
|
|
{ |
413
|
|
|
$this->doGetRequest(array('getpage' => '/home/home.lua', 'logout' => '1')); |
414
|
|
|
} |
415
|
|
|
else |
416
|
|
|
{ |
417
|
|
|
$formfields = array( |
418
|
|
|
'getpage' => '../html/de/menus/menu2.html', |
419
|
|
|
'security:command/logout' => 'logout', |
420
|
|
|
); |
421
|
|
|
$this->doPostForm($formfields); |
422
|
|
|
} |
423
|
|
|
} |
424
|
|
|
|
425
|
|
|
|
426
|
|
|
/** |
427
|
|
|
* the error method just throws an Exception |
428
|
|
|
* |
429
|
|
|
* @param string $message an error message for the Exception |
430
|
|
|
*/ |
431
|
|
|
public function error($message = null) |
432
|
|
|
{ |
433
|
|
|
throw new Exception($message); |
434
|
|
|
} |
435
|
|
|
|
436
|
|
|
|
437
|
|
|
/** |
438
|
|
|
* a getter for the session ID |
439
|
|
|
* |
440
|
|
|
* @return string $this->sid |
441
|
|
|
*/ |
442
|
|
|
public function getSID() |
443
|
|
|
{ |
444
|
|
|
return $this->sid; |
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
/** |
448
|
|
|
* log a message |
449
|
|
|
* |
450
|
|
|
* @param $message string the message to log |
451
|
|
|
*/ |
452
|
|
|
public function logMessage($message) |
453
|
|
|
{ |
454
|
|
|
if ( $this->config->getItem('newline') == false ) |
455
|
|
|
{ |
456
|
|
|
$this->config->setItem('newline', (PHP_OS == 'WINNT') ? "\r\n" : "\n"); |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
if ( $this->config->getItem('logging') == 'console' ) |
460
|
|
|
{ |
461
|
|
|
echo $message; |
462
|
|
|
} |
463
|
|
|
else if ( $this->config->getItem('logging') == 'silent' || $this->config->getItem('logging') == false ) |
|
|
|
|
464
|
|
|
{ |
465
|
|
|
// do nothing |
466
|
|
|
} |
467
|
|
|
else |
468
|
|
|
{ |
469
|
|
|
if ( is_writable($this->config->getItem('logging')) || is_writable(dirname($this->config->getItem('logging'))) ) |
470
|
|
|
{ |
471
|
|
|
file_put_contents($this->config->getItem('logging'), $message . $this->config->getItem('newline'), FILE_APPEND); |
472
|
|
|
} |
473
|
|
|
else |
474
|
|
|
{ |
475
|
|
|
echo('Error: Cannot log to non-writeable file or dir: ' . $this->config->getItem('logging')); |
476
|
|
|
} |
477
|
|
|
} |
478
|
|
|
} |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
class fritzbox_api_config { |
482
|
|
|
protected $config = array(); |
483
|
|
|
|
484
|
|
|
public function __construct() |
485
|
|
|
{ |
486
|
|
|
# use the new .lua login method in current (end 2012) labor and newer firmwares (Fritz!OS 5.50 and up) |
487
|
|
|
$this->setItem('use_lua_login_method', true); |
488
|
|
|
|
489
|
|
|
# set to your Fritz!Box IP address or DNS name (defaults to fritz.box), for remote config mode, use the dyndns-name like example.dyndns.org |
490
|
|
|
$this->setItem('fritzbox_ip', 'fritz.box'); |
491
|
|
|
|
492
|
|
|
# if needed, enable remote config here |
493
|
|
|
#$this->setItem('enable_remote_config', true); |
|
|
|
|
494
|
|
|
#$this->setItem('remote_config_user', 'test'); |
|
|
|
|
495
|
|
|
#$this->setItem('remote_config_password', 'test123'); |
|
|
|
|
496
|
|
|
|
497
|
|
|
# set to your Fritz!Box username, if login with username is enabled (will be ignored, when remote config is enabled) |
498
|
|
|
$this->setItem('username', false); |
499
|
|
|
|
500
|
|
|
# set to your Fritz!Box password (defaults to no password) |
501
|
|
|
$this->setItem('password', false); |
502
|
|
|
|
503
|
|
|
# set the logging mechanism (defaults to console logging) |
504
|
|
|
$this->setItem('logging', 'console'); // output to the console |
505
|
|
|
#$this->setItem('logging', 'silent'); // do not output anything, be careful with this logging mode |
|
|
|
|
506
|
|
|
#$this->setItem('logging', 'tam.log'); // the path to a writeable logfile |
|
|
|
|
507
|
|
|
|
508
|
|
|
# the newline character for the logfile (does not need to be changed in most cases) |
509
|
|
|
$this->setItem('newline', (PHP_OS == 'WINNT') ? "\r\n" : "\n"); |
510
|
|
|
} |
511
|
|
|
|
512
|
|
|
/* gets an item from the config |
513
|
|
|
* |
514
|
|
|
* @param $item string the item to get |
515
|
|
|
* @return mixed the value of the item |
516
|
|
|
*/ |
517
|
|
|
public function getItem($item = 'all') |
518
|
|
|
{ |
519
|
|
|
if ( $item == 'all' ) |
520
|
|
|
{ |
521
|
|
|
return $this->config; |
522
|
|
|
} |
523
|
|
|
elseif ( isset($this->config[$item]) ) |
524
|
|
|
{ |
525
|
|
|
return $this->config[$item]; |
526
|
|
|
} |
527
|
|
|
return false; |
528
|
|
|
} |
529
|
|
|
|
530
|
|
|
/* sets an item into the config |
531
|
|
|
* |
532
|
|
|
* @param $item string the item to set |
533
|
|
|
* @param $value mixed the value to store into the item |
534
|
|
|
*/ |
535
|
|
|
public function setItem($item, $value) |
536
|
|
|
{ |
537
|
|
|
$this->config[$item] = $value; |
538
|
|
|
} |
539
|
|
|
} |
540
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.