source: sandbox/2.2.0.2/expressoMail1_2/inc/class.SieveS.inc.php @ 4240

Revision 4240, 9.2 KB checked in by airton, 13 years ago (diff)

Ticket #1844 - Corrigir o suporte a REFERRAL no servico de filtro sieve

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2
3//Conecta com o Servidor e o serviço Sieve;
4class SieveS{
5               
6        var $host;
7        var $port;
8        var $user;
9        var $pass;
10        var $proxy;
11       
12        var $implementation;
13        var $saslmethods;
14        var $extensions;
15        var $starttls_avail;
16        var $socket;
17        var $socket_timeout;
18       
19        var $scriptlist;
20        var $activescript;
21        var $errstr;
22        var $errnum;
23        var $ScriptS;
24       
25        function SieveS(){
26               
27                $this->host = $_SESSION['phpgw_info']['expressomail']['email_server']['imapSieveServer'];
28                $this->port = $_SESSION['phpgw_info']['expressomail']['email_server']['imapSievePort'];
29                $this->user = $_SESSION['phpgw_info']['expressomail']['user']['account_lid'];   
30                $this->pass = $_SESSION['phpgw_info']['expressomail']['user']['passwd'];
31                $this->proxy = '';
32               
33                $this->socket_timeout = 5;
34                $this->implementation = array('unknown');
35                $this->saslmethods        = array('unknown');
36                $this->extensions         = array('unknown');
37                $this->starttls_avail = false;
38                $this->scriptlist     = array();
39                $this->activescript   = '';
40                $this->errstr             = '';
41                $this->errnum             = '';
42               
43        }       
44       
45        function start(){
46                // Cria a conexao;
47                if(!isset($this->socket)){
48                        $this->socket = fsockopen($this->host, $this->port, $this->errnum, $this->errstr, "60");
49
50                }
51                // Verifica a conexao;
52                if(!$this->socket){
53                        return "não conectado";
54                }
55               
56                $said = $this->read();
57                if (!preg_match("/timsieved/i",$said)) {
58                    $this->close();
59                    $this->errstr = "start: bad response from $this->host: $said";
60                    return false;
61                }
62               
63                if (preg_match("/IMPLEMENTATION/",$said)){
64                  while (!preg_match("/^OK/",$said)) {
65                    if (preg_match("/^\"IMPLEMENTATION\" +\"(.*)\"/",$said,$bits)){
66                                $this->implementation = $bits[1];
67                    }
68                    elseif (preg_match("/^\"SASL\" +\"(.*)\"/",$said,$bits)) {
69                                $auth_types = $bits[1];
70                                $this->saslmethods = split(" ", $auth_types);
71                    }
72                    elseif (preg_match("/^\"SIEVE\" +\"(.*)\"/",$said,$bits)) {
73                                $extensions = $bits[1];
74                                $this->extensions = split(" ", $extensions);
75                    }
76                elseif (preg_match("/^\"STARTTLS\"/",$said)){
77                   $this->starttls_avail = true;
78                }
79                    $said = $this->read();
80                  }
81                }
82                else
83                {
84                    // assume cyrus v1.
85                    if (preg_match("/\"(.+)\" +\"(.+)\"/",$said,$bits)) {
86                                $this->implementation = $bits[1];
87                                $sasl_str = $bits[2];  // should look like: SASL={PLAIN,...}
88                    }
89                        if (preg_match("/SASL=\{(.+)\}/",$sasl_str,$morebits)) {
90                            $auth_types = $morebits[1];
91                            $this->saslmethods = split(", ", $auth_types);
92                        }else {
93                                // a bit desperate if we get here.
94                                $this->implementation = $said;
95                                $this->saslmethods = $said;
96                    }
97                }
98               
99                $authstr = $this->proxy . "\x00" . $this->user . "\x00" . $this->pass;
100                $encoded = base64_encode($authstr);             
101                $len = strlen($encoded);
102
103                //fputs($this->socket,"AUTHENTICATE \"PLAIN\" \{$len+}\r\n");
104                //fputs($this->socket,"$encoded\r\n");
105
106                fwrite($this->socket, 'AUTHENTICATE "PLAIN" {' . $len . '+}' . "\r\n");
107                fwrite($this->socket,"$encoded\r\n");
108               
109                $said = $this->read();
110       
111                if (preg_match("/NO/",$said)) {
112                    $this->close();
113                    $this->errstr = "start: authentication failure connecting to $this->host";
114                    return false;
115                }
116                elseif (!preg_match("/OK/",$said)) {
117                    $this->close();
118                    $this->errstr = "start: bad authentication response from $this->host: $said";
119                    return false;
120                }
121       
122                return true;
123               
124        }
125       
126        function close(){
127       
128                if(!$this->socket){
129                        return true;   
130                }       
131                fputs($this->socket,"LOGOUT\r\n");
132                $rc = fclose($this->socket);
133                if($rc != 1){
134                        $this->errstr = "close: failed closing socket to $this->server";
135                        return false;
136                }
137                return true;
138        }
139       
140        function read(){
141       
142                $buffer = '';
143               
144                // Verifca a conexao;
145                if(!$this->socket){
146                        return $buffer;
147                }
148               
149                //Funções do php
150                socket_set_timeout($this->socket,$this->socket_timeout);
151                socket_set_blocking($this->socket,true);
152               
153                //Lê um caracter de cada vez e o adiciona na variavel buffer;
154                while ( is_resource( $this -> socket ) && ( ! feof( $this -> socket ) ) )
155                {
156                        $char = fread($this->socket,1);
157                       
158                        $status = socket_get_status($this->socket);
159                        if($status['timed_out'])
160                                return $buffer;
161                       
162                        if(($char == "\n") || ($char == "\r")){
163                                if($char == "\r")
164                                        fread($this->socket,1);
165                                return $buffer;
166                        }
167                        $buffer .= $char;
168                }
169                return $buffer;
170        }
171/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
172// Manipulação dos scripts
173/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
174               
175        function listscripts(){
176               
177                $bits = '';
178
179                //Verifica a conexao
180                if(!is_resource($this->socket)){
181                        $this->errstr = "listscripts: sem conexão para o servidor $this->host";
182                        return false;
183                }
184
185                $scripts = array();
186                fputs($this->socket,"LISTSCRIPTS\r\n");
187       
188                $said = $this->read();
189               
190                // DEBUG: Para compatibilizar o sieve com o REFERRAL
191                $tmp = array();
192        if ( preg_match('|^BYE \(REFERRAL "(sieve://)?([^/"]+)"\)|', $said, $tmp) ){
193                        // Redefine a configuracao do servidor sieve, baseado no referral
194                        $this->host = $tmp[2];
195                        // Forca reiniciar a conexao, mas agora para o novo servidor
196                        $this->close ();
197                        unset ($this->socket);
198                        $this->start ();
199
200                        // Excuta novamente esta funcao (libscripts) para continuar a sequncia do codigo
201                        // Chama-la recursivamente nao funciona. A funcao fica em loop
202                        if(!is_resource($this->socket)){
203                                $this->errstr = "listscripts: sem conexao para o servidor $this->host";
204                                return false;
205                        }
206                        fputs($this->socket,"LISTSCRIPTS\r\n");
207                        $said = $this->read();
208        }
209
210               
211                while (is_resource($this->socket) && (!preg_match("/^OK/",$said) && !preg_match("/^NO/",$said))) {
212       
213                    // Cyrus v1 script lines look like '"script*"' with the
214                    // asterisk denoting the active script. Cyrus v2 script
215                    // lines will look like '"script" ACTIVE' if active.
216       
217                    if (preg_match("/^\"(.+)\"\s*(.+)*$/m",$said,$bits)) {
218                        if (preg_match("/\*$/",$bits[1])){
219                            $bits[1] = preg_replace("/\*$/","",$bits[1]);
220                            $this->activescript = $bits[1];
221                        }
222                        if (isset($bits[2]) && $bits[2] == 'ACTIVE')
223                            $this->activescript = $bits[1];
224                        array_push($scripts,$bits[1]);
225                    }
226                    $said = $this->read();
227                }
228       
229                if (preg_match("/^OK/",$said)) {
230                    $this->scriptlist = $scripts;
231            return $this->scriptlist;
232        }
233               
234        }
235       
236        // Pega o conteudo do script no servidor       
237        function getscript(){
238
239                $scriptfile = $this->listscripts();
240               
241                // verifica se existe o script;
242                if($scriptfile == ""){
243                        return "Falta o script";
244                }
245               
246                if(!$this->socket){
247                        return "Falha na conexao";     
248                }
249               
250                $script = '';
251               
252                fputs($this->socket,"GETSCRIPT \"$scriptfile[0]\"\r\n");
253                $said = $this->read();
254                while ((!preg_match("/^OK/",$said)) && (!preg_match("/^NO/",$said))) {
255                    // replace newlines which read() removed
256                    if (!preg_match("/\n$/",$said)) $said .= "\n";
257                    $script .= $said;
258                    $said = $this->read();
259                }
260               
261                if($said == "OK"){
262                        return $script;
263                }else{
264                        return false;
265                }
266        }
267
268        //envia para o servidor o nome do script($scriptfile) e seu conteudo($script)
269        function putscript ($scriptfile,$script) {
270                if (!isset($scriptfile)) {
271                    $this->errstr = "Não foi possível enviar o script para o servidor";
272                    return false;
273            }
274                if (!isset($script)) {
275                    $this->errstr = "Não foi possível enviar o script para o servidor";
276                    return false;
277            }
278                if (!$this->socket) {
279                    $this->errstr = "Sem conexão com o servidor $this->server";
280                    return false;
281            }
282       
283                $len = strlen($script);
284
285                //fputs($this->socket,"PUTSCRIPT \"$scriptfile\" \{$len+}\r\n");
286                //fputs($this->socket,"$script\r\n");
287       
288                fwrite($this->socket, 'PUTSCRIPT "'.$scriptfile.'" {' . $len . '+}' . "\r\n"); 
289                fwrite($this->socket,"$script\r\n");
290       
291                $said = '';
292                while ($said == '') {
293                    $said = $this->read();
294                }
295         
296            if (preg_match("/^OK/",$said)) {
297                    return true;
298                }
299       
300            $this->errstr = "Não foi possível enviar o $scriptfile: $said";
301            return false;
302    }
303   
304    // Ativa o script para o servico sieve;
305    function activatescript ($scriptfile) {
306                if (!isset($scriptfile)) {
307                    $this->errstr = "activatescript: no script file specified";
308                    return false;
309            }
310       
311            if (!$this->socket) {
312                    $this->errstr = "activatescript: no connection open to $this->server";
313                    return false;
314            }
315       
316                fputs($this->socket,"SETACTIVE \"$scriptfile\"\r\n");
317       
318                $said = $this->read();
319       
320                if (preg_match("/^OK/",$said)) {
321                    return true;
322            }
323       
324                $this->errstr = "activatescript: could not activate script $scriptfile: $said";
325            return false;
326    }
327
328    // Deleta o script do serviço sieve;
329    function deletescript ($scriptName) {
330        if(!isset($scriptName)){
331                $this->errstr = "deletescript: no script file specified";
332                return false;
333        }
334       
335        // Verifica a conexão;
336        if(!$this->socket){
337                $this->errstr = "deletescript : no connection open to $this->server";
338                return false;
339        }
340   
341        fputs($this->socket,"DELETESCRIPT \"$scriptName\"\r\n");
342       
343        $said = $this->read();
344       
345        if(preg_match("/^OK/",$said)) {
346                return true;   
347        }
348       
349        $this->errstr = "deletescript: could not delete script $scriptName: $said";
350        return false;
351    }
352}
353?>
Note: See TracBrowser for help on using the repository browser.