[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 /* 3 * $Id: class.SieveSession.inc.php 20316 2006-02-20 12:44:19Z lkneschke $ 4 * 5 * Copyright 2002 Stephen Grier <stephengrier@users.sourceforge.net> 6 * 7 * See the inclosed smartsieve-NOTICE file for conditions of use and distribution. 8 */ 9 10 11 /* 12 * class SieveSession provides an interface to a sieve server, such 13 * as Cyrus timsieved, via the managesieve protocol. 14 * 15 */ 16 class SieveSession { 17 18 var $server; /* sieve server to open session to. */ 19 var $port; /* port to connect to. */ 20 var $proxy; /* proxy authorization user. */ 21 var $uid; /* authentication user. */ 22 var $passwd; /* authentication user's password. */ 23 var $implentation; /* server implementation and version. */ 24 var $saslmethods; /* array: SASL auth methods server supports. */ 25 var $extensions; /* array: sieve extensions server supports. */ 26 var $starttls_avail; /* boolean: will server do starttls? */ 27 var $socket; /* file pointer to open socket. */ 28 var $socket_timeout; /* socket timeout in seconds. */ 29 var $scriptlist; /* array: user's scripts on the server. */ 30 var $activescript; /* the currently active script on server (if any). */ 31 var $errstr; /* error text. */ 32 33 /* 34 * class constructor. 35 */ 36 function SieveSession ($server='127.0.0.1', $port='2000', $uid, $passwd, $proxy='', $socket_timeout=2) { 37 38 $this->server = $server; 39 $this->port = $port; 40 $this->uid = $uid; 41 $this->passwd = $passwd; 42 $this->proxy = $proxy; 43 $this->socket_timeout = $socket_timeout; 44 45 $this->implementation = array('unknown'); 46 $this->saslmethods = array('unknown'); 47 $this->extensions = array('unknown'); 48 $this->starttls_avail = false; 49 $this->scriptlist = array(); 50 $this->activescript = ''; 51 $this->errstr = ''; 52 53 } 54 // end constructor 55 56 57 // class methods 58 59 /* 60 * start a sieve session. open a socket to $this->server, read and 61 * note server capabilities, and then attempt to authenticate the 62 * user. 63 */ 64 function start () { 65 66 if(!isset($this->socket)){ 67 $this->socket = fsockopen($this->server, $this->port, $this->errnum, $this->errstr, "60"); 68 } 69 if (!$this->socket) { 70 return false; 71 } 72 73 $said = $this->read(); 74 if (!preg_match("/timsieved/i",$said)) { 75 $this->close(); 76 $this->errstr = "start: bad response from $this->server: $said"; 77 return false; 78 } 79 80 // If response starts ""IMPLEMENTATION" "(..." server is Cyrus version 2. 81 // else, we will assume Cyrus version 1. 82 83 if (preg_match("/IMPLEMENTATION/",$said)) 84 { 85 while (!preg_match("/^OK/",$said)) { 86 if (preg_match("/^\"IMPLEMENTATION\" +\"(.*)\"/",$said,$bits)) 87 $this->implementation = $bits[1]; 88 elseif (preg_match("/^\"SASL\" +\"(.*)\"/",$said,$bits)) { 89 $auth_types = $bits[1]; 90 $this->saslmethods = split(" ", $auth_types); 91 } 92 elseif (preg_match("/^\"SIEVE\" +\"(.*)\"/",$said,$bits)) { 93 $extensions = $bits[1]; 94 $this->extensions = split(" ", $extensions); 95 } 96 elseif (preg_match("/^\"STARTTLS\"/",$said)) 97 $this->starttls_avail = true; 98 $said = $this->read(); 99 } 100 } 101 else 102 { 103 // assume cyrus v1. 104 if (preg_match("/\"(.+)\" +\"(.+)\"/",$said,$bits)) { 105 $this->implementation = $bits[1]; 106 $sasl_str = $bits[2]; // should look like: SASL={PLAIN,...} 107 if (preg_match("/SASL=\{(.+)\}/",$sasl_str,$morebits)) { 108 $auth_types = $morebits[1]; 109 $this->saslmethods = split(", ", $auth_types); 110 } 111 } 112 else { 113 // a bit desperate if we get here. 114 $this->implementation = $said; 115 $this->saslmethods = $said; 116 } 117 } 118 119 // $said = $this->read(); /* retrieve \n following OK. */ 120 121 $authstr = $this->proxy . "\x00" . $this->uid . "\x00" . $this->passwd; 122 $encoded = base64_encode($authstr); 123 $len = strlen($encoded); 124 fputs($this->socket,"AUTHENTICATE \"PLAIN\" {". $len ."+}\r\n"); 125 fputs($this->socket,"$encoded\r\n"); 126 $said = $this->read(); 127 128 if (preg_match("/NO/",$said)) { 129 $this->close(); 130 $this->errstr = "start: authentication failure connecting to $this->server"; 131 return false; 132 } 133 elseif (!preg_match("/OK/",$said)) { 134 $this->close(); 135 $this->errstr = "start: bad authentication response from $this->server: $said"; 136 return false; 137 } 138 139 return true; 140 } 141 142 /* 143 * end the session. logout and close the socket. 144 */ 145 function close () { 146 147 if (!$this->socket) { 148 return true; 149 } 150 fputs($this->socket,"LOGOUT\r\n"); 151 $rc = fclose ($this->socket); 152 if ($rc != 1) { 153 $this->errstr = "close: failed closing socket to $this->server"; 154 return false; 155 } 156 return true; 157 } 158 159 /* 160 * read a line from socket. 161 * line might end in either a newline, or a CRLF, in which case 162 * we will need to retrieve the newline also. 163 */ 164 function read () { 165 166 $buffer = ''; 167 168 if (!$this->socket) 169 return $buffer; 170 171 socket_set_timeout($this->socket,$this->socket_timeout); 172 socket_set_blocking($this->socket,true); 173 174 /* read one character at a time and add to $buffer. */ 175 while (!feof($this->socket)) { 176 $char = fread($this->socket,1); 177 178 $status = socket_get_status($this->socket); 179 if ($status['timed_out']) 180 return $buffer; 181 182 /* return $buffer if we've reached end on line. 183 * if line ends with CRLF, fetch the \n also. */ 184 if (($char == "\n") || ($char == "\r")) { 185 if ($char == "\r") 186 fread($this->socket,1); 187 return $buffer; 188 } 189 $buffer .= $char; 190 } 191 return $buffer; 192 } 193 194 195 /* 196 * return an array containing the list of sieve scripts on the 197 * server belonging to the current user. 198 */ 199 function listscripts () { 200 if (!$this->socket) { 201 $this->errstr = "listscripts: no connection open to $this->server"; 202 return false; 203 } 204 205 $scripts = array(); 206 207 fputs($this->socket,"LISTSCRIPTS\r\n"); 208 209 $said = $this->read(); 210 while (!preg_match("/^OK/",$said) && !preg_match("/^NO/",$said)) { 211 212 // Cyrus v1 script lines look like '"script*"' with the 213 // asterisk denoting the active script. Cyrus v2 script 214 // lines will look like '"script" ACTIVE' if active. 215 216 if (preg_match("/^\"(.+)\"\s*(.+)*$/m",$said,$bits)) { 217 if (preg_match("/\*$/",$bits[1])){ 218 $bits[1] = preg_replace("/\*$/","",$bits[1]); 219 $this->activescript = $bits[1]; 220 } 221 if (isset($bits[2]) && $bits[2] == 'ACTIVE') 222 $this->activescript = $bits[1]; 223 array_push($scripts,$bits[1]); 224 } 225 $said = $this->read(); 226 } 227 228 if (preg_match("/^OK/",$said)) { 229 $this->scriptlist = $scripts; 230 return true; 231 } 232 233 $this->errstr = "listscripts: could not get list of scripts: $said"; 234 return false; 235 } 236 237 238 /* 239 * return the contents of the sieve script $scriptfile, retrieved 240 * from the server, or false if the script does not exist. 241 */ 242 function getscript ($scriptfile) { 243 if (!isset($scriptfile)) { 244 $this->errstr = "getscript: no script file specified"; 245 return false; 246 } 247 if (!$this->socket) { 248 $this->errstr = "getscript: no connection open to $this->server"; 249 return false; 250 } 251 252 $script = ''; 253 254 fputs($this->socket,"GETSCRIPT \"$scriptfile\"\r\n"); 255 256 $said = $this->read(); 257 while ((!preg_match("/^OK/",$said)) && (!preg_match("/^NO/",$said))) { 258 // replace newlines which read() removed 259 if (!preg_match("/\n$/",$said)) $said .= "\n"; 260 $script .= $said; 261 $said = $this->read(); 262 } 263 264 if (preg_match("/^OK/",$said)) { 265 if ($script == '') { 266 $this->errstr = "getscript: zero length script"; 267 return false; 268 } 269 return $script; 270 } 271 272 $this->errstr = "getscript: could not get script $scriptfile: $said"; 273 return false; 274 } 275 276 277 /* 278 * set $scriptfile as the active sieve script. 279 */ 280 function activatescript ($scriptfile) { 281 if (!isset($scriptfile)) { 282 $this->errstr = "activatescript: no script file specified"; 283 return false; 284 } 285 286 if (!$this->socket) { 287 $this->errstr = "activatescript: no connection open to $this->server"; 288 return false; 289 } 290 291 fputs($this->socket,"SETACTIVE \"$scriptfile\"\r\n"); 292 293 $said = $this->read(); 294 295 if (preg_match("/^OK/",$said)) { 296 return true; 297 } 298 299 $this->errstr = "activatescript: could not activate script $scriptfile: $said"; 300 return false; 301 } 302 303 304 /* 305 * check that the user will not exceed their storage quota 306 * by uploading script $scriptname of size $size bytes. 307 */ 308 function havespace ($scriptname, $size) { 309 if (!$this->socket) { 310 $this->errstr = 'havespace: no connection open to ' . $this->server; 311 return false; 312 } 313 if (!$scriptname){ 314 $this->errstr = 'havespace: no script name specified'; 315 return false; 316 } 317 if (!$size){ 318 $this->errstr = 'havespace: script size not specified'; 319 return false; 320 } 321 322 fputs($this->socket,"HAVESPACE \"$scriptname\" $size\r\n"); 323 324 $said = $this->read(); 325 326 if (preg_match("/^OK/",$said)) { 327 return true; 328 } 329 330 $this->errstr = "havespace: $said"; 331 return false; 332 } 333 334 335 /* 336 * upload the script $script to the server. save it as $scriptfile. 337 * the script will not be active. call activatescript() to do this. 338 */ 339 function putscript ($scriptfile,$script) 340 { 341 if (!isset($scriptfile)) { 342 $this->errstr = "putscript: no script file specified"; 343 return false; 344 } 345 if (!isset($script)) { 346 $this->errstr = "putscript: no script specified"; 347 return false; 348 } 349 if (!$this->socket) { 350 $this->errstr = "putscript: no connection open to $this->server"; 351 return false; 352 } 353 354 if (extension_loaded('mbstring') || @dl(PHP_SHLIB_PREFIX.'mbstring.'.PHP_SHLIB_SUFFIX)) 355 { 356 $len = mb_strlen($script,'latin1'); 357 } 358 else 359 { 360 $len = strlen($script); 361 } 362 fputs($this->socket,"PUTSCRIPT \"$scriptfile\" {". $len ."+}\r\n"); 363 fputs($this->socket,"$script\r\n"); 364 365 $said = ''; 366 while ($said == '') { 367 $said = $this->read(); 368 } 369 370 if (preg_match("/^OK/",$said)) { 371 return true; 372 } 373 374 $this->errstr = "putscript: could not put script '$scriptfile': $said"; 375 return false; 376 } 377 378 379 /* 380 * delete the script $scriptname. 381 */ 382 function deletescript ($scriptname) { 383 if (!$this->socket) { 384 $this->errstr = "deletescript: no connection open to $this->server"; 385 return false; 386 } 387 if (!$scriptname){ 388 $this->errstr = 'deletescript: no script name specified'; 389 return false; 390 } 391 392 fputs($this->socket,"DELETESCRIPT \"$scriptname\"\r\n"); 393 394 $said = $this->read(); 395 396 if (preg_match("/^OK/",$said)) { 397 return true; 398 } 399 400 $this->errstr = "deletescript: could not delete script '$scriptname': $said"; 401 return false; 402 } 403 404 405 } 406 // end SieveSession class 407 408 409 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |