/[imapfilter]/imapfilter/socket.c
ViewVC logotype

Diff of /imapfilter/socket.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.19 by lefcha, Fri Jul 26 14:42:01 2002 UTC revision 1.19.2.5 by lefcha, Sat Mar 8 01:37:01 2003 UTC
# Line 24  int sockpri = -1;              /* Main socket used m Line 24  int sockpri = -1;              /* Main socket used m
24  int sockaux = -1;               /* Auxiliary socked used when another  int sockaux = -1;               /* Auxiliary socked used when another
25                                     connection is needed. */                                     connection is needed. */
26  #ifdef SSL_TLS  #ifdef SSL_TLS
27  static SSL *ssl;  static SSL *sslpri = NULL;
28    static SSL *sslaux = NULL;
29  #endif  #endif
30    
31    
# Line 36  int init_connection(int *sock, char *ser Line 37  int init_connection(int *sock, char *ser
37  {  {
38      struct sockaddr_in sa;      struct sockaddr_in sa;
39      struct hostent *he;      struct hostent *he;
40    #ifdef SSL_TLS
41  #ifndef SSL_TLS      SSL **ssl = (sock == &sockpri ? &sslpri : &sslaux);
42    #else
43      if (protocol != SSL_DISABLED) {      if (protocol != SSL_DISABLED) {
44          error("imapfilter: SSL not supported by this build\n");          error("imapfilter: SSL not supported by this build\n");
45          return ERROR_SSL;          return ERROR_SSL;
# Line 77  int init_connection(int *sock, char *ser Line 79  int init_connection(int *sock, char *ser
79          if (!ssl_init(sock, protocol)) {          if (!ssl_init(sock, protocol)) {
80              if (sock == &sockpri)              if (sock == &sockpri)
81                  info("Connected to %s using %s.\n", serv,                  info("Connected to %s using %s.\n", serv,
82                       SSL_get_cipher(ssl));                       SSL_get_cipher(*ssl));
83              return 0;              return 0;
84          } else          } else
85              return ERROR_SSL;              return ERROR_SSL;
86      else      else
87          ssl = NULL;          *ssl = NULL;
88  #endif  #endif
89    
90      if (sock == &sockpri)      if (sock == &sockpri)
# Line 104  int ssl_init(int *sock, unsigned int pro Line 106  int ssl_init(int *sock, unsigned int pro
106      SSL_METHOD *method = NULL;      SSL_METHOD *method = NULL;
107      X509 *cert;      X509 *cert;
108      char *c;      char *c;
109      EVP_MD *evp;      const EVP_MD *evp;
110      unsigned char digest[EVP_MAX_MD_SIZE];      unsigned char digest[EVP_MAX_MD_SIZE];
111        SSL **ssl = (sock == &sockpri ? &sslpri : &sslaux);
112    
113      SSL_library_init();      SSL_library_init();
114    
# Line 124  int ssl_init(int *sock, unsigned int pro Line 127  int ssl_init(int *sock, unsigned int pro
127      if (!(ctx = SSL_CTX_new(method)))      if (!(ctx = SSL_CTX_new(method)))
128          return ERROR_SSL;          return ERROR_SSL;
129    
130      if (!(ssl = SSL_new(ctx)))      if (!(*ssl = SSL_new(ctx)))
131          return ERROR_SSL;          return ERROR_SSL;
132    
133      SSL_set_fd(ssl, *sock);      SSL_set_fd(*ssl, *sock);
134    
135      e = SSL_connect(ssl);      e = SSL_connect(*ssl);
136    
137      if (e < 0) {      if (e <= 0) {
138            SSL_get_error(*ssl, e);
139          error("imapfilter: initiating SSL connection; %s",          error("imapfilter: initiating SSL connection; %s",
140                ERR_error_string(e, NULL));                ERR_error_string(ERR_get_error(), NULL));
141          return ERROR_SSL;          return ERROR_SSL;
142      }      }
143      /* Get server's certificate. */      /* Get server's certificate. */
144      if (!(cert = SSL_get_peer_certificate(ssl)))      if (!(cert = SSL_get_peer_certificate(*ssl)))
145          return ERROR_SSL;          return ERROR_SSL;
146    
147      if (!(c = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0)))      if (!(c = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0)))
# Line 174  int ssl_init(int *sock, unsigned int pro Line 178  int ssl_init(int *sock, unsigned int pro
178  int close_connection(int *sock)  int close_connection(int *sock)
179  {  {
180  #ifdef SSL_TLS  #ifdef SSL_TLS
181      if (ssl) {      SSL **ssl = (sock == &sockpri ? &sslpri : &sslaux);
182          SSL_shutdown(ssl);  
183          SSL_free(ssl);      if (*ssl) {
184            SSL_shutdown(*ssl);
185            SSL_free(*ssl);
186            *ssl = NULL;
187      }      }
188  #endif  #endif
189    
# Line 195  int close_connection(int *sock) Line 202  int close_connection(int *sock)
202   */   */
203  int socket_read(int *sock, char *buf)  int socket_read(int *sock, char *buf)
204  {  {
205      int f, r, s;      int f, e, s;
206      fd_set fds;      fd_set fds;
207      struct timeval tv;      struct timeval tv;
208      struct timeval *tvp = NULL;      struct timeval *tvp = NULL;
209    #ifdef SSL_TLS
210        SSL **ssl = (sock == &sockpri ? &sslpri : &sslaux);
211    #endif
212    
213      r = 0;      e = 0;
214      s = 1;      s = 1;
215    
216      memset(buf, 0, RESPONSE_BUF);      memset(buf, 0, RESPONSE_BUF);
# Line 217  int socket_read(int *sock, char *buf) Line 227  int socket_read(int *sock, char *buf)
227      FD_SET(*sock, &fds);      FD_SET(*sock, &fds);
228    
229  #ifdef SSL_TLS  #ifdef SSL_TLS
230      if (ssl) {      if (*ssl) {
231          if (SSL_pending(ssl)  
232              || ((s = select(*sock + 1, &fds, NULL, NULL, tvp)) > 0          for (;;) {
233                  && FD_ISSET(*sock, &fds)))              if (SSL_pending(*ssl) ||
234              r = SSL_read(ssl, buf, RESPONSE_BUF - 1);                  ((s = select(*sock + 1, &fds, NULL, NULL, tvp)) > 0 &&
235                     FD_ISSET(*sock, &fds)))
236                    e = SSL_read(*ssl, buf, RESPONSE_BUF - 1);
237    
238                if (e > 0)
239                    break;
240    
241                switch (SSL_get_error(*ssl, e)) {
242                case SSL_ERROR_WANT_READ:
243                case SSL_ERROR_WANT_WRITE:
244                    continue;
245                case SSL_ERROR_ZERO_RETURN:
246                     return ERROR_NETWORK;
247                case SSL_ERROR_SYSCALL:
248                case SSL_ERROR_SSL:
249                    fatal(ERROR_NETWORK, "imapfilter: reading data; %s",
250                          ERR_error_string(ERR_get_error(), NULL));
251                default:
252                    fatal(ERROR_NETWORK,
253                        "imapfilter: undefined ssl error while reading data\n");
254                }
255            }
256      } else      } else
257  #endif  #endif
258          if ((s = select(*sock + 1, &fds, NULL, NULL, tvp)) > 0      {
259              && FD_ISSET(*sock, &fds))          if ((s = select(*sock + 1, &fds, NULL, NULL, tvp)) > 0 &&
260          r = read(*sock, buf, RESPONSE_BUF - 1);              FD_ISSET(*sock, &fds))
261                e = read(*sock, buf, RESPONSE_BUF - 1);
262            
263            if (e == -1)
264                fatal(ERROR_NETWORK, "imapfilter: reading data; %s",
265                      strerror(errno));
266            else if (e == 0)
267                return ERROR_NETWORK;
268        }
269    
270      fcntl(*sock, F_SETFL, f);      fcntl(*sock, F_SETFL, f);
271    
272      if (s == -1)      if (s == -1)
273          fatal(ERROR_NETWORK, "imapfilter: waiting input from socket; %s\n",          fatal(ERROR_NETWORK, "imapfilter: waiting to read from socket; %s\n",
274                strerror(errno));                strerror(errno));
275      else if (!s)      else if (!s)
276          fatal(ERROR_NETWORK,          fatal(ERROR_NETWORK,
277                "imapfilter: timeout period expired while waiting data\n");                "imapfilter: timeout period expired while waiting to read "
278                  "data\n");
 #ifdef SSL_TLS  
     if (ssl) {  
         if (r < 0)  
             fatal(ERROR_NETWORK, "imapfilter: reading data; %s",  
                   ERR_error_string(r, NULL));  
     } else  
 #endif  
     if (r == -1)  
         fatal(ERROR_NETWORK, "imapfilter: reading data; %s",  
               strerror(errno));  
279    
280      return 0;      return 0;
281  }  }
# Line 257  int socket_read(int *sock, char *buf) Line 286  int socket_read(int *sock, char *buf)
286   */   */
287  int socket_write(int *sock, char *data)  int socket_write(int *sock, char *data)
288  {  {
289        int f, e, s;
290        fd_set fds;
291        struct timeval tv;
292        struct timeval *tvp = NULL;
293  #ifdef SSL_TLS  #ifdef SSL_TLS
294      int e;      SSL **ssl = (sock == &sockpri ? &sslpri : &sslaux);
295    #endif
296    
297        e = 0;
298        s = 1;
299    
300        if (timeout >= 0) {
301            tv.tv_sec = timeout;
302            tv.tv_usec = 0;
303            tvp = &tv;
304        }
305        f = fcntl(*sock, F_GETFL, 0);
306        fcntl(*sock, F_SETFL, f | O_NONBLOCK);
307    
308        FD_ZERO(&fds);
309        FD_SET(*sock, &fds);
310    
311      if (ssl) {  #ifdef SSL_TLS
312          e = SSL_write(ssl, data, strlen(data));      if (*ssl) {
313          if (e <= 0)          for (;;) {
314              fatal(ERROR_NETWORK,              if ((s = select(*sock + 1, NULL, &fds, NULL, tvp) > 0 &&
315                    "imapfilter: sending data; %s",                   FD_ISSET(*sock, &fds)))
316                    ERR_error_string(e, NULL));                  e = SSL_write(*ssl, data, strlen(data));
317    
318                if (e > 0)
319                    break;
320    
321                switch (SSL_get_error(*ssl, e)) {
322                case SSL_ERROR_WANT_READ:
323                case SSL_ERROR_WANT_WRITE:
324                    continue;
325                case SSL_ERROR_ZERO_RETURN:
326                     return ERROR_NETWORK;
327                case SSL_ERROR_SYSCALL:
328                case SSL_ERROR_SSL:
329                    fatal(ERROR_NETWORK, "imapfilter: writing data; %s",
330                          ERR_error_string(ERR_get_error(), NULL));
331                default:
332                    fatal(ERROR_NETWORK,
333                        "imapfilter: undefined ssl error while writing data\n");
334                }
335            }
336      } else      } else
337  #endif  #endif
338      if (write(*sock, data, strlen(data)) == -1)      {
339          fatal(ERROR_NETWORK, "imapfilter: sending data; %s",          if ((s = select(*sock + 1, NULL, &fds, NULL, tvp)) > 0 &&
340                FD_ISSET(*sock, &fds))
341                e = write(*sock, data, strlen(data));
342            
343            if (e == -1)
344                fatal(ERROR_NETWORK, "imapfilter: writing data; %s",
345                      strerror(errno));
346        }
347    
348        fcntl(*sock, F_SETFL, f);
349    
350        if (s == -1)
351            fatal(ERROR_NETWORK, "imapfilter: waiting to write to socket; %s\n",
352                strerror(errno));                strerror(errno));
353        else if (!s)
354            fatal(ERROR_NETWORK,
355                  "imapfilter: timeout period expired while waiting to write "
356                  "data\n");
357    
358      return 0;      return 0;
359  }  }

Legend:
Removed from v.1.19  
changed lines
  Added in v.1.19.2.5

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26