1 <?php
2 /*
3 * This code is part of GOsa (http://www.gosa-project.org)
4 * Copyright (C) 2003-2008 GONICUS GmbH
5 *
6 * ID: $$Id$$
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
23 class Socket_Client
24 {
25 private $host = "";
26 private $port = "";
27 private $timeout= "";
28 private $errno = "";
29 private $errstr = "";
30 private $b_data_send = FALSE;
31 private $handle = NULL;
32 private $bytes_read = 0;
33 private $error = "";
34 private $is_error = FALSE;
35 private $b_encrypt = FALSE;
37 /* Crypto information */
38 private $td= NULL;
39 private $ckey= "";
40 private $ks;
41 private $iv;
44 public function __construct($host, $port, $connect = TRUE, $timeout = 3){
45 $this->host= $host;
46 $this->port= $port;
47 $this->timeout= $timeout;
48 $this->reset_error();
50 /* Connect if needed */
51 if($connect){
52 $this->open();
53 }
54 }
57 public function setEncryptionKey($key)
58 {
59 if(!function_exists("mcrypt_get_iv_size")){
60 $this->set_error(_("No PHP mcrypt module found!"));
61 $this->ckey = "";
62 $this->b_encrypt = FALSE;
63 }
65 if ($this->connected()){
66 $this->ckey = substr(md5($key), 0, $this->ks);
67 $this->b_encrypt = TRUE;
68 }
70 return($this->b_encrypt);
71 }
74 private function encrypt($data)
75 {
76 if($this->b_encrypt){
77 mcrypt_generic_init($this->td, $this->ckey, $this->iv);
78 $data = base64_encode(mcrypt_generic($this->td, $data));
79 }
80 return($data);
81 }
84 private function decrypt($data)
85 {
86 /* decrypt data */
87 if($this->b_encrypt && strlen($data)){
88 $data = base64_decode($data);
89 mcrypt_generic_init($this->td, $this->ckey, $this->iv);
90 $data = mdecrypt_generic($this->td, $data);
91 }
92 return($data);
93 }
96 public function connected()
97 {
98 return ($this->handle == TRUE);
99 }
102 public function open()
103 {
104 $this->reset_error();
105 $this->handle = @fsockopen($this->host, $this->port, $this->errno, $this->errstr, $this->timeout);
106 if(!$this->handle){
107 $this->handle = NULL;
108 $this->set_error(sprintf(_("Socket connection to '%s:%s' failed: %s"),$this->host,$this->port,$this->errstr));
109 }else{
110 $this->b_data_send = TRUE;
112 /* Open the cipher */
113 $this->td = mcrypt_module_open('rijndael-128', '', 'cbc', '');
115 /* Create the IV and determine the keysize length */
116 $this->iv = substr(md5('GONICUS GmbH'),0, mcrypt_enc_get_iv_size($this->td));
117 $this->ks = mcrypt_enc_get_key_size($this->td);
118 }
119 }
122 public function set_error($str)
123 {
124 $this->is_error =TRUE;
125 $this->error=$str;
126 }
129 public function reset_error()
130 {
131 $this->is_error =FALSE;
132 $this->error = "";
133 }
136 public function is_error()
137 {
138 return($this->is_error);
139 }
142 public function get_error()
143 {
144 return $this->error;
145 }
148 public function write($data){
149 if($this->handle){
150 $data = $this->encrypt($data);
151 fputs($this->handle, $data."\n");
152 $this->b_data_send = TRUE;
153 }else{
154 $this->b_data_send = FALSE;
155 }
157 return $this->b_data_send;
158 }
161 public function read()
162 {
163 // Output the request results
164 $this->reset_error();
165 $str = "";
166 $data = "test";
167 socket_set_timeout($this->handle,$this->timeout);
168 stream_set_blocking($this->handle,0);
169 $start = microtime(TRUE);
171 /* Read while
172 * nothing was read yet
173 * the timelimit reached
174 * there is not data left on the socket.
175 */
176 while(TRUE){
177 usleep(10000);
178 $data = fread($this->handle, 1024000);
179 if($data && strlen($data)>0) {
180 $str .= $data;
181 } else {
182 if(strlen($str) != 0){
184 /* We got <xml> but </xml> is still missing, keep on reading */
185 if(preg_match("/<\/xml>/",$this->decrypt($str))){
186 break;
187 }
188 }
189 }
190 if((microtime(TRUE) - $start) > $this->timeout ){
191 $this->set_error(sprintf(_("Socket timeout of %s seconds reached!"),$this->timeout));
192 break;
193 }
194 }
195 $this->bytes_read = strlen($str);
196 $this->b_data_send = FALSE;
197 $str = $this->decrypt($str);
198 return($str);
199 }
202 public function bytes_read()
203 {
204 return $this->bytes_read;
205 }
208 public function close()
209 {
210 if($this->handle){
211 fclose($this->handle);
212 }
214 /* Terminate decryption handle and close module */
215 @mcrypt_generic_deinit($this->td);
216 }
217 }
218 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
219 ?>