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

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26