source: github/plugins/password/drivers/directadmin.php @ 028c1f3

HEADcourier-fixdev-browser-capabilitiespdorelease-0.6release-0.7release-0.8
Last change on this file since 028c1f3 was 028c1f3, checked in by alecpl <alec@…>, 4 years ago
  • Property mode set to 100644
File size: 12.0 KB
Line 
1<?php
2
3/**
4 * DirectAdmin Password Driver
5 *
6 * Driver to change passwords via DirectAdmin Control Panel
7 *
8 * @version 1.0
9 * @author Victor Benincasa <vbenincasa@gmail.com>
10 *
11 */
12
13
14function password_save($curpass, $passwd){
15
16    $rcmail = rcmail::get_instance();
17    $Socket = new HTTPSocket;
18
19    $da_user    = $_SESSION['username'];
20    $da_curpass = $curpass;
21    $da_newpass = $passwd;
22    $da_host    = $rcmail->config->get('password_directadmin_host');
23    $da_port    = $rcmail->config->get('password_directadmin_port');
24
25    $Socket->connect($da_host,$da_port); 
26    $Socket->set_method('POST');
27    $Socket->query('/CMD_CHANGE_EMAIL_PASSWORD',
28        array(
29            'email'             => $da_user,
30            'oldpassword'       => $da_curpass,
31            'password1'         => $da_newpass,
32            'password2'         => $da_newpass,
33            'api'                       => '1'
34    ));
35    $response = $Socket->fetch_parsed_body();
36
37        //console("DA error response: $response[text] [$da_user]");
38
39    if($Socket->result_status_code <> 200)
40        return PASSWORD_CONNECT_ERROR;
41    elseif($response['error'] == 1){ //Error description: $response[text]
42        return PASSWORD_ERROR;
43    }else 
44        return PASSWORD_SUCCESS;
45
46}
47
48
49/**
50 * Socket communication class.
51 *
52 * Originally designed for use with DirectAdmin's API, this class will fill any HTTP socket need.
53 *
54 * Very, very basic usage:
55 *   $Socket = new HTTPSocket;
56 *   echo $Socket->get('http://user:pass@somesite.com/somedir/some.file?query=string&this=that');
57 *
58 * @author Phi1 'l0rdphi1' Stier <l0rdphi1@liquenox.net>
59 * @package HTTPSocket
60 * @version 2.6
61 */
62class HTTPSocket {
63
64    var $version = '2.6';
65   
66    /* all vars are private except $error, $query_cache, and $doFollowLocationHeader */
67
68    var $method = 'GET';
69
70    var $remote_host;
71    var $remote_port;
72    var $remote_uname;
73    var $remote_passwd;
74
75    var $result;
76    var $result_header;
77    var $result_body;
78    var $result_status_code;
79
80    var $lastTransferSpeed;
81
82    var $bind_host;
83
84    var $error = array();
85    var $warn = array();
86    var $query_cache = array();
87
88    var $doFollowLocationHeader = TRUE;
89    var $redirectURL;
90
91    var $extra_headers = array();
92
93    /**
94     * Create server "connection".
95     *
96     */
97    function connect($host, $port = '' )
98    {
99        if (!is_numeric($port))
100        {
101            $port = 80;
102        }
103
104        $this->remote_host = $host;
105        $this->remote_port = $port;
106    }
107
108    function bind( $ip = '' )
109    {
110        if ( $ip == '' )
111        {
112            $ip = $_SERVER['SERVER_ADDR'];
113        }
114
115        $this->bind_host = $ip;
116    }
117
118    /**
119     * Change the method being used to communicate.
120     *
121     * @param string|null request method. supports GET, POST, and HEAD. default is GET
122     */
123    function set_method( $method = 'GET' )
124    {
125        $this->method = strtoupper($method);
126    }
127
128    /**
129     * Specify a username and password.
130     *
131     * @param string|null username. defualt is null
132     * @param string|null password. defualt is null
133     */
134    function set_login( $uname = '', $passwd = '' )
135    {
136        if ( strlen($uname) > 0 )
137        {
138            $this->remote_uname = $uname;
139        }
140
141        if ( strlen($passwd) > 0 )
142        {
143            $this->remote_passwd = $passwd;
144        }
145
146    }
147
148    /**
149     * Query the server
150     *
151     * @param string containing properly formatted server API. See DA API docs and examples. Http:// URLs O.K. too.
152     * @param string|array query to pass to url
153     * @param int if connection KB/s drops below value here, will drop connection
154     */
155    function query( $request, $content = '', $doSpeedCheck = 0 )
156    {
157        $this->error = $this->warn = array();
158        $this->result_status_code = NULL;
159
160        // is our request a http:// ... ?
161        if (preg_match('!^http://!i',$request))
162        {
163            $location = parse_url($request);
164            $this->connect($location['host'],$location['port']);
165            $this->set_login($location['user'],$location['pass']);
166           
167            $request = $location['path'];
168            $content = $location['query'];
169
170            if ( strlen($request) < 1 )
171            {
172                $request = '/';
173            }
174
175        }
176
177        $array_headers = array(
178            'User-Agent' => "HTTPSocket/$this->version",
179            'Host' => ( $this->remote_port == 80 ? $this->remote_host : "$this->remote_host:$this->remote_port" ),
180            'Accept' => '*/*',
181            'Connection' => 'Close' );
182
183        foreach ( $this->extra_headers as $key => $value )
184        {
185            $array_headers[$key] = $value;
186        }
187
188        $this->result = $this->result_header = $this->result_body = '';
189
190        // was content sent as an array? if so, turn it into a string
191        if (is_array($content))
192        {
193            $pairs = array();
194
195            foreach ( $content as $key => $value )
196            {
197                $pairs[] = "$key=".urlencode($value);
198            }
199
200            $content = join('&',$pairs);
201            unset($pairs);
202        }
203
204        $OK = TRUE;
205
206        // instance connection
207        if ($this->bind_host)
208        {
209            $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
210            socket_bind($socket,$this->bind_host);
211
212            if (!@socket_connect($socket,$this->remote_host,$this->remote_port))
213            {
214                $OK = FALSE;
215            }
216
217        }
218        else
219        {
220            $socket = @fsockopen( $this->remote_host, $this->remote_port, $sock_errno, $sock_errstr, 10 );
221        }
222
223        if ( !$socket || !$OK )
224        {
225            $this->error[] = "Can't create socket connection to $this->remote_host:$this->remote_port.";
226            return 0;
227        }
228
229        // if we have a username and password, add the header
230        if ( isset($this->remote_uname) && isset($this->remote_passwd) )
231        {
232            $array_headers['Authorization'] = 'Basic '.base64_encode("$this->remote_uname:$this->remote_passwd");
233        }
234
235        // for DA skins: if $this->remote_passwd is NULL, try to use the login key system
236        if ( isset($this->remote_uname) && $this->remote_passwd == NULL )
237        {
238            $array_headers['Cookie'] = "session={$_SERVER['SESSION_ID']}; key={$_SERVER['SESSION_KEY']}";
239        }
240
241        // if method is POST, add content length & type headers
242        if ( $this->method == 'POST' )
243        {
244            $array_headers['Content-type'] = 'application/x-www-form-urlencoded';
245            $array_headers['Content-length'] = strlen($content);
246        }
247        // else method is GET or HEAD. we don't support anything else right now.
248        else
249        {
250            if ($content)
251            {
252                $request .= "?$content";
253            }
254        }
255
256        // prepare query
257        $query = "$this->method $request HTTP/1.0\r\n";
258        foreach ( $array_headers as $key => $value )
259        {
260            $query .= "$key: $value\r\n";
261        }
262        $query .= "\r\n";
263
264        // if POST we need to append our content
265        if ( $this->method == 'POST' && $content )
266        {
267            $query .= "$content\r\n\r\n";
268        }
269
270        // query connection
271        if ($this->bind_host)
272        {
273            socket_write($socket,$query);
274
275            // now load results
276            while ( $out = socket_read($socket,2048) )
277            {
278                $this->result .= $out;
279            }
280        }
281        else
282        {
283            fwrite( $socket, $query, strlen($query) );
284
285            // now load results
286            $this->lastTransferSpeed = 0;
287            $status = socket_get_status($socket);
288            $startTime = time();
289            $length = 0;
290            $prevSecond = 0;
291            while ( !feof($socket) && !$status['timed_out'] )
292            {
293                $chunk = fgets($socket,1024);
294                $length += strlen($chunk);
295                $this->result .= $chunk;
296
297                $elapsedTime = time() - $startTime;
298
299                if ( $elapsedTime > 0 )
300                {
301                    $this->lastTransferSpeed = ($length/1024)/$elapsedTime;
302                }
303
304                if ( $doSpeedCheck > 0 && $elapsedTime > 5 && $this->lastTransferSpeed < $doSpeedCheck )
305                {
306                    $this->warn[] = "kB/s for last 5 seconds is below 50 kB/s (~".( ($length/1024)/$elapsedTime )."), dropping connection...";
307                    $this->result_status_code = 503;
308                    break;
309                }
310
311            }
312
313            if ( $this->lastTransferSpeed == 0 )
314            {
315                $this->lastTransferSpeed = $length/1024;
316            }
317
318        }
319       
320        list($this->result_header,$this->result_body) = split("\r\n\r\n",$this->result,2);
321
322        if ($this->bind_host)
323        {
324            socket_close($socket);
325        }
326        else
327        {
328            fclose($socket);
329        }
330
331        $this->query_cache[] = $query;
332
333
334        $headers = $this->fetch_header();
335
336        // what return status did we get?
337        if (!$this->result_status_code)
338        {
339            preg_match("#HTTP/1\.. (\d+)#",$headers[0],$matches);
340            $this->result_status_code = $matches[1];
341        }
342
343        // did we get the full file?
344        if ( !empty($headers['content-length']) && $headers['content-length'] != strlen($this->result_body) )
345        {
346            $this->result_status_code = 206;
347        }
348
349        // now, if we're being passed a location header, should we follow it?
350        if ($this->doFollowLocationHeader)
351        {
352            if ($headers['location'])
353            {
354                $this->redirectURL = $headers['location'];
355                $this->query($headers['location']);
356            }
357        }
358       
359    }
360
361    function getTransferSpeed()
362    {
363        return $this->lastTransferSpeed;
364    }
365
366    /**
367     * The quick way to get a URL's content :)
368     *
369     * @param string URL
370     * @param boolean return as array? (like PHP's file() command)
371     * @return string result body
372     */
373    function get($location, $asArray = FALSE )
374    {
375        $this->query($location);
376
377        if ( $this->get_status_code() == 200 )
378        {
379            if ($asArray)
380            {
381                return split("\n",$this->fetch_body());
382            }
383
384            return $this->fetch_body();
385        }
386
387        return FALSE;
388    }
389
390    /**
391     * Returns the last status code.
392     * 200 = OK;
393     * 403 = FORBIDDEN;
394     * etc.
395     *
396     * @return int status code
397     */
398    function get_status_code()
399    {
400        return $this->result_status_code;
401    }
402
403    /**
404     * Adds a header, sent with the next query.
405     *
406     * @param string header name
407     * @param string header value
408     */
409    function add_header($key,$value)
410    {
411        $this->extra_headers[$key] = $value;
412    }
413
414    /**
415     * Clears any extra headers.
416     *
417     */
418    function clear_headers()
419    {
420        $this->extra_headers = array();
421    }
422
423    /**
424     * Return the result of a query.
425     *
426     * @return string result
427     */
428    function fetch_result()
429    {
430        return $this->result;
431    }
432
433    /**
434     * Return the header of result (stuff before body).
435     *
436     * @param string (optional) header to return
437     * @return array result header
438     */
439    function fetch_header( $header = '' )
440    {
441        $array_headers = split("\r\n",$this->result_header);
442       
443        $array_return = array( 0 => $array_headers[0] );
444        unset($array_headers[0]);
445
446        foreach ( $array_headers as $pair )
447        {
448            list($key,$value) = split(": ",$pair,2);
449            $array_return[strtolower($key)] = $value;
450        }
451
452        if ( $header != '' )
453        {
454            return $array_return[strtolower($header)];
455        }
456
457        return $array_return;
458    }
459
460    /**
461     * Return the body of result (stuff after header).
462     *
463     * @return string result body
464     */
465    function fetch_body()
466    {
467        return $this->result_body;
468    }
469
470    /**
471     * Return parsed body in array format.
472     *
473     * @return array result parsed
474     */
475    function fetch_parsed_body()
476    {
477        parse_str($this->result_body,$x);
478        return $x;
479    }
480
481}
482
483?>
Note: See TracBrowser for help on using the repository browser.