add some code for traffic stats
[ZNCAdmin.git] / zncadmin / ZNCServerV1.class.php
1 <?php
2 /* ZNCServerV1.class.php - ZNC Server Class - ZNCAdmin
3  * Copyright (C) 2011-2012  Philipp Kreil (pk910)
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18
19 $classinfo = array(
20     "name" => "ZNCServerV1",
21     "version" => 1.000,
22 );
23
24 class ZNCServerV1 {
25     private $host, $port;
26     private $connector;
27
28     public function ZNCServerV1($host, $port, $connector = NULL) {
29         $this->host = $host;
30         $this->port = $port;
31         if($connector == NULL)
32             $connector = new HTTPConnector();
33         $this->connector = $connector;
34     }
35
36     public function login($user, $pass) {
37         $post = array(
38             "user" => $user,
39             "pass" => $pass,
40             "submitted" => "1"
41         );
42         $this->connector->post("http://".$this->host.":".$this->port."/login", $post);
43         $http = $this->connector->get("http://".$this->host.":".$this->port."/?cookie_check=true");
44         $logged_in = !preg_match("/errorbar/i", $http);
45
46         return $logged_in;
47     }
48
49     public function getUserList() {
50         $html = $this->connector->get("http://".$this->host.":".$this->port."/mods/global/webadmin/listusers");
51         $exp = explode('<div class="toptable">', $html);
52         $exp = explode('</div>', $exp[1]);
53         $exp = explode('<tbody>', $exp[0]);
54         $exp = explode('</tbody>', $exp[1]);
55         $list = explode('<tr class=', $exp[0]);
56         $userlist = array();
57         for($i = 1; $i < count($list); $i++) {
58             $userdata = array();
59             $exp = explode('<td>', $list[$i]);
60             $exp2 = explode('</td>', $exp[2]);
61             $userdata['user'] = $exp2[0];
62             $exp2 = explode('</td>', $exp[3]);
63             $userdata['server'] = $exp2[0];
64             $exp2 = explode('</td>', $exp[4]);
65             $userdata['clients'] = $exp2[0];
66             $userlist[] = $userdata;
67         }
68         return $userlist;
69     }
70
71     public function getSeenList() {
72         $html = $this->connector->get("http://".$this->host.":".$this->port."/mods/global/lastseen/");
73         $exp = explode('<div class="toptable">', $html);
74         $exp = explode('</div>', $exp[1]);
75         $exp = explode('<tbody>', $exp[0]);
76         $exp = explode('</tbody>', $exp[1]);
77         $list = explode('<tr class=', $exp[0]);
78         $seenlist = array();
79         for($i = 1; $i < count($list); $i++) {
80             $userdata = array();
81             $exp = explode('<td>', $list[$i]);
82
83             $exp2 = explode('</td>', $exp[1]);
84             $userdata['user'] = $exp2[0];
85             $exp2 = explode('</td>', $exp[2]);
86             $userdata['seen'] = $exp2[0];
87             $userdata['seen_unix'] = strtotime($exp2[0]);
88             $exp2 = explode('</td>', $exp[3]);
89             $userdata['info'] = $exp2[0];
90             $seenlist[] = $userdata;
91         }
92         return $seenlist;
93     }
94
95     public function getTrafficStats() {
96         $html = $this->connector->get("http://".$this->host.":".$this->port."/mods/global/webadmin/traffic");
97     }
98
99     /*
100     $settings array elements:
101         nick
102         altnick
103         ident
104     */
105     public function addZNC($username, $password, $settings, $servers, $modules, $others) {
106         $html = $this->connector->get("http://".$this->host.":".$this->port."/mods/global/webadmin/adduser");
107         $exp = explode('name="_CSRF_Check" value="', $html);
108         $exp = explode('"', $exp[1]);
109         $csrf = $exp[0];
110         $post = array();
111         $post['_CSRF_Check'] = $csrf;
112         $post['submitted'] = '1';
113         //$post['doconnect'] = '1';
114         $post['user'] = $username;
115         $post['password'] = $password;
116         $post['password2'] = $password;
117         $post['nick'] = $settings['nick'];
118         $post['altnick'] = $settings['altnick'];
119         $post['ident'] = $settings['ident'];
120         $post['statusprefix'] = '*';
121         $post['loadmod'] = array();
122         foreach($modules as $name => $args) {
123             $post['loadmod'][] = $name;
124             if($args != "")
125                 $post['modargs_'.$name] = $args;
126         }
127
128         foreach($others as $name => $value) {
129             $post[$name] = $value;
130         }
131
132         $html = $this->connector->post("http://".$this->host.":".$this->port."/mods/global/webadmin/adduser", $post);
133
134         if(!preg_match("/Invalid Submission/i", $html)) {
135             if(!$this->addNetwork($username, $settings, $servers, $others)) {
136                 return false;
137             }
138             return !preg_match("/Invalid Submission/i", $html);
139         }
140         return !preg_match("/Invalid Submission/i", $html);
141     }
142
143     public function addNetwork($username, $settings, $servers, $others) {
144         $html = $this->connector->get("http://".$this->host.":".$this->port."/mods/global/webadmin/addnetwork?user=".$username);
145         $exp = explode('name="_CSRF_Check" value="', $html);
146         $exp = explode('"', $exp[1]);
147         $csrf = $exp[0];
148         $post = array();
149         $post['_CSRF_Check'] = $csrf;
150         $post['submitted'] = '1';
151         $post['network'] = 'default';
152         $post['nick'] = $settings['nick'];
153         $post['altnick'] = $settings['altnick'];
154         $post['ident'] = $settings['ident'];
155         $post['servers'] = implode("\n", $servers);
156         $post['doconnect'] = '1';
157         $post['floodprotection'] = '1';
158         $post['floodrate'] = '1.0';
159         $post['floodburst'] = '4';
160         $post['user'] = $username;
161
162         foreach($others as $name => $value) {
163             $post[$name] = $value;
164         }
165
166         $html = $this->connector->post("http://".$this->host.":".$this->port."/mods/global/webadmin/addnetwork", $post);
167         return !preg_match("/Invalid Submission/i", $html);
168     }
169
170     public function delZNC($username) {
171         $html = $this->connector->get("http://".$this->host.":".$this->port."/mods/global/webadmin/deluser?user=".$username);
172         $exp = explode('name="_CSRF_Check" value="', $html);
173         $exp = explode('"', $exp[1]);
174         $csrf = $exp[0];
175         $post = array();
176         $post['_CSRF_Check'] = $csrf;
177         $post['submitted'] = '1';
178         $post['user'] = $username;
179         $this->connector->post("http://".$this->host.":".$this->port."/mods/global/webadmin/deluser", $post);
180     }
181
182     private function parseHTMLFields($html, &$post) {
183         preg_match_all("<input ([^\>]*)>", $html, $matches);
184         foreach($matches[0] as $input) {
185             $fields = array(0 => "");
186             $esc = false; $str = false;
187             $fieldid = 0;
188             for($i = 0; $i < strlen($input); $i++) {
189                 if($esc) {
190                     $esc = false;
191                     $fields[$fieldid] .= $input[$i];
192                     continue;
193                 }
194                 if($input[$i] == "\\") {
195                     $esc = true;
196                 }
197                 if($input[$i] == "\"") {
198                     $str = !$str;
199                     continue;
200                 }
201                 if($input[$i] == " " && !$str) {
202                     $fields[++$fieldid] = "";
203                     continue;
204                 }
205                 $fields[$fieldid] .= $input[$i];
206             }
207             $cfields = array();
208             foreach($fields as $field) {
209                 $fieldexp = explode("=", $field, 2);
210                 if(count($fieldexp) != 2) continue;
211                 $cfields[$fieldexp[0]] = $fieldexp[1];
212             }
213             $name = $cfields['name'];
214             switch($cfields['type']) {
215                 case "text":
216                 case "hidden":
217                     $value = $cfields['value'];
218                     break;
219                 case "checkbox":
220                     if($cfields['checked']) {
221                         $value = ($cfields['value'] ? $cfields['value'] : "1");
222                     } else
223                         $value = null;
224                     break;
225                 default:
226                     $value = null;
227             }
228             if($name && $value) {
229                 if(array_key_exists($name, $post)) {
230                     if(!is_array($post[$name])) {
231                         $cvalue = $post[$name];
232                         $post[$name] = array();
233                         $post[$name][] = $cvalue;
234                     }
235                     $post[$name][] = $value;
236                 } else
237                     $post[$name] = $value;
238             }
239         }
240         //textareas
241         $textareas = explode("<textarea ", $html);
242         for($i = 1; $i < count($textareas); $i++) {
243             $exp = explode(">", $textareas[$i]);
244             $name = explode("name=\"", $exp[0]);
245             $name = explode("\"", $name[1]);
246             $name = $name[0];
247             $content = explode("</textarea", $exp[1]);
248             $content = $content[0];
249             $post[$name] = $content;
250         }
251         //select boxes
252         $selectboxes = explode("<select ", $html);
253         for($j = 1; $j < count($selectboxes); $j++) {
254             $exp = explode(">", $selectboxes[$j], 2);
255             $name = explode("name=\"", $exp[0]);
256             $name = explode("\"", $name[1]);
257             $name = $name[0];
258             $content = explode("</select", $exp[1]);
259             $content = $content[0];
260             preg_match_all("<option ([^\>]*)>", $content, $matches);
261             foreach($matches[0] as $input) {
262                 $fields = array(0 => "");
263                 $esc = false; $str = false;
264                 $fieldid = 0;
265                 for($i = 0; $i < strlen($input); $i++) {
266                     if($esc) {
267                         $esc = false;
268                         $fields[$fieldid] .= $input[$i];
269                         continue;
270                     }
271                     if($input[$i] == "\\") {
272                         $esc = true;
273                     }
274                     if($input[$i] == "\"") {
275                         $str = !$str;
276                         continue;
277                     }
278                     if($input[$i] == " " && !$str) {
279                         $fields[++$fieldid] = "";
280                         continue;
281                     }
282                     $fields[$fieldid] .= $input[$i];
283                 }
284                 $cfields = array();
285                 foreach($fields as $field) {
286                     $fieldexp = explode("=", $field, 2);
287                     if(count($fieldexp) != 2) continue;
288                     $cfields[$fieldexp[0]] = $fieldexp[1];
289                 }
290                 if(!$post[$name] || $cfields['selected']) {
291                     $post[$name] = $cfields['value'];
292                 }
293             }
294         }
295     }
296
297     public function editZNC($username, $password = NULL, $new_servers = NULL, $add_modules = NULL, $del_modules = NULL, $others = NULL) {
298         $html = $this->connector->get("http://".$this->host.":".$this->port."/mods/global/webadmin/edituser?user=".$username);
299         if(preg_match("/No such username/i", $html)) return false;
300         $post = array();
301         $post['loadmod'] = array();
302         $this->parseHTMLFields($html, $post);
303         if($password) {
304             $post['password'] = $password;
305             $post['password2'] = $password;
306         }
307         if($new_servers) {
308             $post['servers'] = implode("\n", $new_servers);
309         }
310         if($add_modules) {
311             foreach($add_modules as $name => $args) {
312                 $post['loadmod'][] = $name;
313                 if($args != "")
314                     $post['modargs_'.$name] = $args;
315             }
316         }
317         if($del_modules) {
318             foreach($del_modules as $name => $args) {
319                 foreach($post['loadmod'] as $index => $mod) {
320                     if(strtolower($mod) == strtolower($name))
321                         unset($post['loadmod'][$index]);
322                 }
323             }
324         }
325         if($others) {
326             foreach($others as $name => $value) {
327                 $post[$name] = $value;
328             }
329         }
330         $html = $this->connector->post("http://".$this->host.":".$this->port."/mods/global/webadmin/edituser?user=".$username, $post);
331         return !preg_match("/Invalid Submission/i", $html);
332     }
333
334     public function blockZNC($username, $block) {
335         $html = $this->connector->get("http://".$this->host.":".$this->port."/mods/global/webadmin/edituser?user=".$username);
336         $handle = fopen('/home/srvx/neonserv/log.txt', 'a');
337         fwrite($handle, "$html\r\n");
338         fclose($handle);
339         if(preg_match("/No such username/i", $html)) return ERR_USER_NOT_FOUND;
340         $post = array();
341         $post['user'] = $username;
342         $post['loadmod'] = array();
343         $this->parseHTMLFields($html, $post);
344         if(!$post['embed_blockuser_presented']) return ERR_MODULE_NOT_FOUND;
345         if(!($post['embed_blockuser_block'] xor $block)) return ERR_OK;
346         $post['embed_blockuser_block'] = ($block ? "1" : null);
347         if(!$block) {
348             $post['doconnect'] = 1;
349         }
350         $html = $this->connector->post("http://".$this->host.":".$this->port."/mods/global/webadmin/edituser", $post);
351         $handle = fopen('/home/srvx/neonserv/log.txt', 'a');
352         fwrite($handle, "$html\r\n");
353         fclose($handle);
354         return (preg_match("/Invalid Submission/i", $html) ? ERR_UNKNOWN : ERR_OK);
355     }
356
357     public function simulZNC($username, $raw, &$errmsg, $server = true) {
358         $html = $this->connector->get("http://".$this->host.":".$this->port."/mods/user/send_raw/");
359         if(preg_match("/Not Found/i", $html)) return ERR_MODULE_NOT_FOUND;
360         $exp = explode('name="_CSRF_Check" value="', $html);
361         $exp = explode('"', $exp[1]);
362         $csrf = $exp[0];
363         $post = array();
364         $post['_CSRF_Check'] = $csrf;
365         $post['submitted'] = '1';
366         $post['network'] = $username.'/default';
367         $post['send_to'] = ($server ? "server" : "client");
368         $post['line'] = $raw;
369         $html = $this->connector->post("http://".$this->host.":".$this->port."/mods/user/send_raw/", $post);
370         return ERR_OK;
371     }
372
373     public function addChan($username, $channel, $key = NULL, $buffer = NULL) {
374         $html = $this->connector->get("http://".$this->host.":".$this->port."/mods/global/webadmin/addchan?user=".$username.'&network=default');
375         if(preg_match("/No such username/i", $html)) return false;
376         $exp = explode('name="_CSRF_Check" value="', $html);
377         $exp = explode('"', $exp[1]);
378         $csrf = $exp[0];
379         $post = array();
380         $post['_CSRF_Check'] = $csrf;
381         $post['submitted'] = '1';
382         $post['network'] = 'default';
383         $post['user'] = $username;
384         $post['name'] = $channel;
385         $exp = explode('name="key" value="', $html);
386         $exp = explode('"', $exp[1]);
387         $default_key = $exp[0];
388         $post['key'] = ($key ? $key : $default_key);
389         $exp = explode('name="buffercount" value="', $html);
390         $exp = explode('"', $exp[1]);
391         $default_buffer = $exp[0];
392         $post['buffercount'] = ($buffer ? $buffer : $default_buffer);
393         $post['defmodes'] = '';
394         $post['save'] = 'true';
395         $post['autoclearchanbuffer'] = 'true';
396         $this->connector->post("http://".$this->host.":".$this->port."/mods/global/webadmin/addchan?user=".$username.'&network=default', $post);
397     }
398
399 }
400
401 ?>