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