/[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.4 by lefcha, Sun Feb 2 17:43:45 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_SYSCALL:
246                case SSL_ERROR_SSL:
247                    fatal(ERROR_NETWORK, "imapfilter: reading data; %s",
248                          ERR_error_string(ERR_get_error(), NULL));
249                default:
250                    fatal(ERROR_NETWORK,
251                        "imapfilter: undefined ssl error while reading data\n");
252                }
253            }
254      } else      } else
255  #endif  #endif
256          if ((s = select(*sock + 1, &fds, NULL, NULL, tvp)) > 0          if ((s = select(*sock + 1, &fds, NULL, NULL, tvp)) > 0 &&
257              && FD_ISSET(*sock, &fds))              FD_ISSET(*sock, &fds))
258          r = read(*sock, buf, RESPONSE_BUF - 1);          e = read(*sock, buf, RESPONSE_BUF - 1);
259    
260        if (e == -1)
261            fatal(ERROR_NETWORK, "imapfilter: reading data; %s",
262                  strerror(errno));
263    
264      fcntl(*sock, F_SETFL, f);      fcntl(*sock, F_SETFL, f);
265    
266      if (s == -1)      if (s == -1)
267          fatal(ERROR_NETWORK, "imapfilter: waiting input from socket; %s\n",          fatal(ERROR_NETWORK, "imapfilter: waiting to read from socket; %s\n",
268                strerror(errno));                strerror(errno));
269      else if (!s)      else if (!s)
270          fatal(ERROR_NETWORK,          fatal(ERROR_NETWORK,
271                "imapfilter: timeout period expired while waiting data\n");                "imapfilter: timeout period expired while waiting to read "
272                  "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));  
273    
274      return 0;      return 0;
275  }  }
# Line 257  int socket_read(int *sock, char *buf) Line 280  int socket_read(int *sock, char *buf)
280   */   */
281  int socket_write(int *sock, char *data)  int socket_write(int *sock, char *data)
282  {  {
283        int f, e, s;
284        fd_set fds;
285        struct timeval tv;
286        struct timeval *tvp = NULL;
287  #ifdef SSL_TLS  #ifdef SSL_TLS
288      int e;      SSL **ssl = (sock == &sockpri ? &sslpri : &sslaux);
289    #endif
290    
291        e = 0;
292        s = 1;
293    
294      if (ssl) {      if (timeout >= 0) {
295          e = SSL_write(ssl, data, strlen(data));          tv.tv_sec = timeout;
296          if (e <= 0)          tv.tv_usec = 0;
297              fatal(ERROR_NETWORK,          tvp = &tv;
298                    "imapfilter: sending data; %s",      }
299                    ERR_error_string(e, NULL));      f = fcntl(*sock, F_GETFL, 0);
300        fcntl(*sock, F_SETFL, f | O_NONBLOCK);
301    
302        FD_ZERO(&fds);
303        FD_SET(*sock, &fds);
304    
305    #ifdef SSL_TLS
306        if (*ssl) {
307            for (;;) {
308                if ((s = select(*sock + 1, NULL, &fds, NULL, tvp) > 0 &&
309                     FD_ISSET(*sock, &fds)))
310                    e = SSL_write(*ssl, data, strlen(data));
311    
312                if (e > 0)
313                    break;
314    
315                switch (SSL_get_error(*ssl, e)) {
316                case SSL_ERROR_WANT_READ:
317                case SSL_ERROR_WANT_WRITE:
318                    continue;
319                case SSL_ERROR_SYSCALL:
320                case SSL_ERROR_SSL:
321                    fatal(ERROR_NETWORK, "imapfilter: writing data; %s",
322                          ERR_error_string(ERR_get_error(), NULL));
323                default:
324                    fatal(ERROR_NETWORK,
325                        "imapfilter: undefined ssl error while writing data\n");
326                }
327            }
328      } else      } else
329  #endif  #endif
330      if (write(*sock, data, strlen(data)) == -1)          if ((s = select(*sock + 1, NULL, &fds, NULL, tvp)) > 0 &&
331          fatal(ERROR_NETWORK, "imapfilter: sending data; %s",              FD_ISSET(*sock, &fds))
332            e = write(*sock, data, strlen(data));
333    
334        if (e == -1)
335            fatal(ERROR_NETWORK, "imapfilter: writing data; %s",
336                  strerror(errno));
337    
338        fcntl(*sock, F_SETFL, f);
339    
340        if (s == -1)
341            fatal(ERROR_NETWORK, "imapfilter: waiting to write to socket; %s\n",
342                strerror(errno));                strerror(errno));
343        else if (!s)
344            fatal(ERROR_NETWORK,
345                  "imapfilter: timeout period expired while waiting to write "
346                  "data\n");
347    
348      return 0;      return 0;
349  }  }

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

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26