Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

conn.c

Go to the documentation of this file.
00001 /* ==================================================================== 
00002  * The Kannel Software License, Version 1.0 
00003  * 
00004  * Copyright (c) 2001-2008 Kannel Group  
00005  * Copyright (c) 1998-2001 WapIT Ltd.   
00006  * All rights reserved. 
00007  * 
00008  * Redistribution and use in source and binary forms, with or without 
00009  * modification, are permitted provided that the following conditions 
00010  * are met: 
00011  * 
00012  * 1. Redistributions of source code must retain the above copyright 
00013  *    notice, this list of conditions and the following disclaimer. 
00014  * 
00015  * 2. Redistributions in binary form must reproduce the above copyright 
00016  *    notice, this list of conditions and the following disclaimer in 
00017  *    the documentation and/or other materials provided with the 
00018  *    distribution. 
00019  * 
00020  * 3. The end-user documentation included with the redistribution, 
00021  *    if any, must include the following acknowledgment: 
00022  *       "This product includes software developed by the 
00023  *        Kannel Group (http://www.kannel.org/)." 
00024  *    Alternately, this acknowledgment may appear in the software itself, 
00025  *    if and wherever such third-party acknowledgments normally appear. 
00026  * 
00027  * 4. The names "Kannel" and "Kannel Group" must not be used to 
00028  *    endorse or promote products derived from this software without 
00029  *    prior written permission. For written permission, please  
00030  *    contact org@kannel.org. 
00031  * 
00032  * 5. Products derived from this software may not be called "Kannel", 
00033  *    nor may "Kannel" appear in their name, without prior written 
00034  *    permission of the Kannel Group. 
00035  * 
00036  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 
00037  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00038  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00039  * DISCLAIMED.  IN NO EVENT SHALL THE KANNEL GROUP OR ITS CONTRIBUTORS 
00040  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,  
00041  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT  
00042  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR  
00043  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
00044  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE  
00045  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,  
00046  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00047  * ==================================================================== 
00048  * 
00049  * This software consists of voluntary contributions made by many 
00050  * individuals on behalf of the Kannel Group.  For more information on  
00051  * the Kannel Group, please see <http://www.kannel.org/>. 
00052  * 
00053  * Portions of this software are based upon software originally written at  
00054  * WapIT Ltd., Helsinki, Finland for the Kannel project.  
00055  */ 
00056 
00057 /* conn.c - implement Connection type
00058  *
00059  * This file implements the interface defined in conn.h.
00060  *
00061  * Richard Braakman
00062  *
00063  * SSL client implementation contributed by
00064  * Jarkko Kovala <jarkko.kovala@iki.fi>
00065  *
00066  * SSL server implementation contributed by
00067  * Stipe Tolj <stolj@wapme.de> for Wapme Systems AG
00068  */
00069 
00070 /* TODO: unlocked_close() on error */
00071 /* TODO: have I/O functions check if connection is open */
00072 /* TODO: have conn_open_tcp do a non-blocking connect() */
00073 
00074 #include <signal.h>
00075 #include <unistd.h>
00076 #include <errno.h>
00077 
00078 #include <sys/types.h>
00079 #include <sys/socket.h>
00080 #include <string.h>
00081 
00082 #include "gwlib/gwlib.h"
00083 
00084 #ifdef HAVE_LIBSSL
00085 #include <openssl/ssl.h>
00086 #include <openssl/err.h>
00087 
00088 static SSL_CTX *global_ssl_context = NULL;
00089 static SSL_CTX *global_server_ssl_context = NULL;
00090 #endif /* HAVE_LIBSSL */
00091 
00092 typedef unsigned long (*CRYPTO_CALLBACK_PTR)(void);
00093 
00094 /*
00095  * This used to be 4096.  It is now 0 so that callers don't have to
00096  * deal with the complexities of buffering (i.e. deciding when to
00097  * flush) unless they want to.
00098  * FIXME: Figure out how to combine buffering sensibly with use of
00099  * conn_register.
00100  */
00101 #define DEFAULT_OUTPUT_BUFFERING 0
00102 #define SSL_CONN_TIMEOUT         30
00103 
00104 struct Connection
00105 {
00106     /* We use separate locks for input and ouput fields, so that
00107      * read and write activities don't have to get in each other's
00108      * way.  If you need both, then acquire the outlock first. */
00109     Mutex *inlock;
00110     Mutex *outlock;
00111     volatile sig_atomic_t claimed;
00112 #ifndef NO_GWASSERT
00113     long claiming_thread;
00114 #endif
00115 
00116     /* fd value is read-only and is not locked */
00117     int fd;
00118 
00119     /* socket state */
00120     enum {yes,no} connected;
00121 
00122     /* Protected by outlock */
00123     Octstr *outbuf;
00124     long outbufpos;   /* start of unwritten data in outbuf */
00125 
00126     /* Try to buffer writes until there are this many octets to send.
00127      * Set it to 0 to get an unbuffered connection. */
00128     unsigned int output_buffering;
00129 
00130     /* Protected by inlock */
00131     Octstr *inbuf;
00132     long inbufpos;    /* start of unread data in inbuf */
00133 
00134     int read_eof;     /* we encountered eof on read */
00135     int io_error;   /* we encountered error on IO operation */
00136 
00137     /* Protected by both locks when updating, so you need only one
00138      * of the locks when reading. */
00139     FDSet *registered;
00140     conn_callback_t *callback;
00141     void *callback_data;
00142     conn_callback_data_destroyer_t *callback_data_destroyer;
00143     /* Protected by inlock */
00144     int listening_pollin;
00145     /* Protected by outlock */
00146     int listening_pollout;
00147 
00148 #ifdef HAVE_LIBSSL
00149     SSL *ssl;
00150     X509 *peer_certificate;
00151 #endif /* HAVE_LIBSSL */
00152 };
00153 
00154 static void unlocked_register_pollin(Connection *conn, int onoff);
00155 static void unlocked_register_pollout(Connection *conn, int onoff);
00156 
00157 /* There are a number of functions that play with POLLIN and POLLOUT flags.
00158  * The general rule is that we always want to poll for POLLIN except when
00159  * we have detected eof (which may be reported as eternal POLLIN), and
00160  * we want to poll for POLLOUT only if there's data waiting in the
00161  * output buffer.  If output buffering is set, we may not want to poll for
00162  * POLLOUT if there's not enough data waiting, which is why we have
00163  * unlocked_try_write. */
00164 
00165 /* Macros to get more information for debugging purposes */
00166 #define unlock_in(conn) unlock_in_real(conn, __FILE__, __LINE__, __func__)
00167 #define unlock_out(conn) unlock_out_real(conn, __FILE__, __LINE__, __func__)
00168 
00169 /* Lock a Connection's read direction, if the Connection is unclaimed */
00170 static void inline lock_in(Connection *conn)
00171 {
00172     gw_assert(conn != NULL);
00173 
00174     if (conn->claimed)
00175         gw_assert(gwthread_self() == conn->claiming_thread);
00176     else
00177         mutex_lock(conn->inlock);
00178 }
00179 
00180 /* Unlock a Connection's read direction, if the Connection is unclaimed */
00181 static void inline unlock_in_real(Connection *conn, char *file, int line, const char *func)
00182 {
00183     int ret;
00184     gw_assert(conn != NULL);
00185 
00186     if (!conn->claimed && (ret = mutex_unlock(conn->inlock)) != 0) {
00187         panic(0, "%s:%ld: %s: Mutex unlock failed. "
00188             "(Called from %s:%ld:%s.)",
00189             __FILE__, (long) __LINE__, __func__,
00190             file, (long) line, func);
00191     }
00192 }
00193 
00194 /* Lock a Connection's write direction, if the Connection is unclaimed */
00195 static void inline lock_out(Connection *conn)
00196 {
00197     gw_assert(conn != NULL);
00198 
00199     if (conn->claimed)
00200         gw_assert(gwthread_self() == conn->claiming_thread);
00201     else
00202         mutex_lock(conn->outlock);
00203 }
00204 
00205 /* Unlock a Connection's write direction, if the Connection is unclaimed */
00206 static void inline unlock_out_real(Connection *conn, char *file, int line, const char *func)
00207 {
00208     int ret;
00209     gw_assert(conn != NULL);
00210 
00211     if (!conn->claimed && (ret = mutex_unlock(conn->outlock)) != 0) {
00212         panic(0, "%s:%ld: %s: Mutex unlock failed. "
00213             "(Called from %s:%ld:%s.)",
00214             __FILE__, (long) __LINE__, __func__,
00215             file, (long) line, func);
00216     }
00217 }
00218 
00219 /* Return the number of bytes in the Connection's output buffer */
00220 static long inline unlocked_outbuf_len(Connection *conn)
00221 {
00222     return octstr_len(conn->outbuf) - conn->outbufpos;
00223 }
00224 
00225 /* Return the number of bytes in the Connection's input buffer */
00226 static long inline unlocked_inbuf_len(Connection *conn)
00227 {
00228     return octstr_len(conn->inbuf) - conn->inbufpos;
00229 }
00230 
00231 /* Send as much data as can be sent without blocking.  Return the number
00232  * of bytes written, or -1 in case of error. */
00233 static long unlocked_write(Connection *conn)
00234 {
00235     long ret = 0;
00236 
00237 #ifdef HAVE_LIBSSL
00238     if (conn->ssl != NULL) {
00239         if (octstr_len(conn->outbuf) - conn->outbufpos > 0)
00240             ret = SSL_write(conn->ssl,
00241                         octstr_get_cstr(conn->outbuf) + conn->outbufpos,
00242                         octstr_len(conn->outbuf) - conn->outbufpos);
00243 
00244         if (ret < 0) {
00245             int SSL_error = SSL_get_error(conn->ssl, ret);
00246 
00247             if (SSL_error == SSL_ERROR_WANT_READ || SSL_error == SSL_ERROR_WANT_WRITE) {
00248                   ret = 0; /* no error */
00249             } else {
00250                 error(errno, "SSL write failed: OpenSSL error %d: %s",
00251                       SSL_error, ERR_error_string(SSL_error, NULL));
00252                 return -1;
00253             }
00254         }
00255     } else
00256 #endif /* HAVE_LIBSSL */
00257         ret = octstr_write_data(conn->outbuf, conn->fd, conn->outbufpos);
00258 
00259     if (ret < 0) {
00260         conn->io_error = 1;
00261         return -1;
00262     }
00263 
00264     conn->outbufpos += ret;
00265 
00266     /* Heuristic: Discard the already-written data if it's more than
00267      * half of the total.  This should keep the buffer size small
00268      * without wasting too many cycles on moving data around. */
00269     if (conn->outbufpos > octstr_len(conn->outbuf) / 2) {
00270         octstr_delete(conn->outbuf, 0, conn->outbufpos);
00271         conn->outbufpos = 0;
00272     }
00273 
00274     if (conn->registered)
00275         unlocked_register_pollout(conn, unlocked_outbuf_len(conn) > 0);
00276 
00277     return ret;
00278 }
00279 
00280 /* Try to empty the output buffer without blocking.  Return 0 for success,
00281  * 1 if there is still data left in the buffer, and -1 for errors. */
00282 static int unlocked_try_write(Connection *conn)
00283 {
00284     long len;
00285 
00286     len = unlocked_outbuf_len(conn);
00287     if (len == 0)
00288         return 0;
00289 
00290     if (len < (long) conn->output_buffering)
00291         return 1;
00292 
00293     if (unlocked_write(conn) < 0)
00294         return -1;
00295 
00296     if (unlocked_outbuf_len(conn) > 0)
00297         return 1;
00298 
00299     return 0;
00300 }
00301 
00302 /* Read whatever data is currently available, up to an internal maximum. */
00303 static void unlocked_read(Connection *conn)
00304 {
00305     unsigned char buf[4096];
00306     long len;
00307 
00308     if (conn->inbufpos > 0) {
00309         octstr_delete(conn->inbuf, 0, conn->inbufpos);
00310         conn->inbufpos = 0;
00311     }
00312 
00313 #ifdef HAVE_LIBSSL
00314     if (conn->ssl != NULL) {
00315         len = SSL_read(conn->ssl, buf, sizeof(buf));
00316     } else
00317 #endif /* HAVE_LIBSSL */
00318         len = read(conn->fd, buf, sizeof(buf));
00319 
00320     if (len < 0) {
00321         if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
00322             return;
00323 #ifdef HAVE_LIBSSL
00324         if (conn->ssl) {
00325             int SSL_error = SSL_get_error(conn->ssl, len);
00326             if (SSL_error == SSL_ERROR_WANT_WRITE || SSL_error == SSL_ERROR_WANT_READ)
00327                 return; /* no error */
00328             error(errno, "SSL read failed: OpenSSL error %d: %s",
00329                       SSL_error, ERR_error_string(SSL_error, NULL));
00330         }
00331         else
00332 #endif /* HAVE_LIBSSL */
00333             error(errno, "Error reading from fd %d:", conn->fd);
00334         conn->io_error = 1;
00335         if (conn->registered)
00336             unlocked_register_pollin(conn, 0);
00337         return;
00338     } else if (len == 0) {
00339         conn->read_eof = 1;
00340         if (conn->registered)
00341             unlocked_register_pollin(conn, 0);
00342     } else {
00343         octstr_append_data(conn->inbuf, buf, len);
00344     }
00345 }
00346 
00347 /* Cut "length" octets from the input buffer and return them as an Octstr */
00348 static Octstr *unlocked_get(Connection *conn, long length)
00349 {
00350     Octstr *result = NULL;
00351 
00352     gw_assert(unlocked_inbuf_len(conn) >= length);
00353     result = octstr_copy(conn->inbuf, conn->inbufpos, length);
00354     conn->inbufpos += length;
00355 
00356     return result;
00357 }
00358 
00359 /* Tell the fdset whether we are interested in POLLIN events, but only
00360  * if the status changed.  (Calling fdset_listen can be expensive if
00361  * it requires synchronization with the polling thread.)
00362  * We must already have the inlock.
00363  */
00364 static void unlocked_register_pollin(Connection *conn, int onoff)
00365 {
00366     gw_assert(conn->registered);
00367 
00368     if (onoff == 1 && !conn->listening_pollin) {
00369         /* Turn it on */
00370         conn->listening_pollin = 1;
00371         fdset_listen(conn->registered, conn->fd, POLLIN, POLLIN);
00372     } else if (onoff == 0 && conn->listening_pollin) {
00373         /* Turn it off */
00374         conn->listening_pollin = 0;
00375         fdset_listen(conn->registered, conn->fd, POLLIN, 0);
00376     }
00377 }
00378 
00379 /* Tell the fdset whether we are interested in POLLOUT events, but only
00380  * if the status changed.  (Calling fdset_listen can be expensive if
00381  * it requires synchronization with the polling thread.)
00382  * We must already have the outlock.
00383  */
00384 static void unlocked_register_pollout(Connection *conn, int onoff)
00385 {
00386     gw_assert(conn->registered);
00387 
00388     if (onoff == 1 && !conn->listening_pollout) {
00389         /* Turn it on */
00390         conn->listening_pollout = 1;
00391         fdset_listen(conn->registered, conn->fd, POLLOUT, POLLOUT);
00392     } else if (onoff == 0 && conn->listening_pollout) {
00393         /* Turn it off */
00394         conn->listening_pollout = 0;
00395         fdset_listen(conn->registered, conn->fd, POLLOUT, 0);
00396     }
00397 }
00398 
00399 #ifdef HAVE_LIBSSL
00400 static int conn_init_client_ssl(Connection *ret, Octstr *certkeyfile)
00401 {
00402     ret->ssl = SSL_new(global_ssl_context);
00403 
00404     /*
00405      * The current thread's error queue must be empty before
00406      * the TLS/SSL I/O operation is attempted, or SSL_get_error()
00407      * will not work reliably.
00408      */
00409     ERR_clear_error();
00410 
00411     if (certkeyfile != NULL) {
00412         SSL_use_certificate_file(ret->ssl, octstr_get_cstr(certkeyfile),
00413                                  SSL_FILETYPE_PEM);
00414         SSL_use_PrivateKey_file(ret->ssl, octstr_get_cstr(certkeyfile),
00415                                 SSL_FILETYPE_PEM);
00416         if (SSL_check_private_key(ret->ssl) != 1) {
00417             error(0, "conn_open_ssl: private key isn't consistent with the "
00418                      "certificate from file %s (or failed reading the file)",
00419                   octstr_get_cstr(certkeyfile));
00420             return -1;
00421         }
00422     }
00423 
00424     /* SSL_set_fd can fail, so check it */
00425     if (SSL_set_fd(ret->ssl, ret->fd) == 0) {
00426         /* SSL_set_fd failed, log error */
00427         error(errno, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL));
00428         return -1;
00429     }
00430 
00431     /*
00432      * make sure the socket is non-blocking while we do SSL_connect
00433      */
00434     if (socket_set_blocking(ret->fd, 0) < 0) {
00435         return -1;
00436     }
00437     BIO_set_nbio(SSL_get_rbio(ret->ssl), 1);
00438     BIO_set_nbio(SSL_get_wbio(ret->ssl), 1);
00439 
00440     SSL_set_connect_state(ret->ssl);
00441     
00442     return 0;
00443 }
00444 
00445 Connection *conn_open_ssl_nb(Octstr *host, int port, Octstr *certkeyfile,
00446                           Octstr *our_host)
00447 {
00448     Connection *ret;
00449 
00450     /* open the TCP connection */
00451     if (!(ret = conn_open_tcp_nb(host, port, our_host))) {
00452         return NULL;
00453     }
00454     
00455     if (conn_init_client_ssl(ret, certkeyfile) == -1) {
00456         conn_destroy(ret);
00457         return NULL;
00458     }
00459     
00460     return ret;
00461 }
00462 
00463 Connection *conn_open_ssl(Octstr *host, int port, Octstr *certkeyfile,
00464               Octstr *our_host)
00465 {
00466     Connection *ret;
00467 
00468     /* open the TCP connection */
00469     if (!(ret = conn_open_tcp(host, port, our_host))) {
00470         return NULL;
00471     }
00472 
00473     if (conn_init_client_ssl(ret, certkeyfile) == -1) {
00474         conn_destroy(ret);
00475         return NULL;
00476     }
00477 
00478     return ret;
00479 }
00480 
00481 #endif /* HAVE_LIBSSL */
00482 
00483 Connection *conn_open_tcp(Octstr *host, int port, Octstr *our_host)
00484 {
00485     return conn_open_tcp_with_port(host, port, 0, our_host);
00486 }
00487 
00488 Connection *conn_open_tcp_nb(Octstr *host, int port, Octstr *our_host)
00489 {
00490   return conn_open_tcp_nb_with_port(host, port, 0, our_host);
00491 }
00492 
00493 Connection *conn_open_tcp_nb_with_port(Octstr *host, int port, int our_port,
00494                        Octstr *our_host)
00495 {
00496   int sockfd;
00497   int done = -1;
00498   Connection *c;
00499 
00500   sockfd = tcpip_connect_nb_to_server_with_port(octstr_get_cstr(host), port,
00501                         our_port, our_host == NULL ?
00502                         NULL : octstr_get_cstr(our_host), &done);
00503   if (sockfd < 0)
00504     return NULL;
00505   c = conn_wrap_fd(sockfd, 0);
00506   if (done != 0) {
00507     c->connected = no;
00508   }
00509   return c;
00510 }
00511 
00512 int conn_is_connected(Connection *conn)
00513 {
00514   return conn->connected == yes ? 0 : -1;
00515 }
00516 
00517 int conn_get_connect_result(Connection *conn)
00518 {
00519   int err;
00520   socklen_t len;
00521 
00522   len = sizeof(err);
00523   if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
00524     return -1;
00525   }
00526   
00527   if (err) {
00528     return -1;
00529   }
00530   
00531   conn->connected = yes;
00532   return 0;
00533 }
00534 
00535 Connection *conn_open_tcp_with_port(Octstr *host, int port, int our_port,
00536         Octstr *our_host)
00537 {
00538     int sockfd;
00539 
00540     sockfd = tcpip_connect_to_server_with_port(octstr_get_cstr(host), port,
00541                            our_port, our_host == NULL ?
00542                            NULL : octstr_get_cstr(our_host));
00543     if (sockfd < 0)
00544     return NULL;
00545     return conn_wrap_fd(sockfd, 0);
00546 }
00547 
00548 
00549 /*
00550  * XXX bad assumption here that conn_wrap_fd for SSL can only happens
00551  * for the server side!!!! FIXME !!!!
00552  */
00553 Connection *conn_wrap_fd(int fd, int ssl)
00554 {
00555     Connection *conn;
00556 
00557     if (socket_set_blocking(fd, 0) < 0)
00558         return NULL;
00559 
00560     conn = gw_malloc(sizeof(*conn));
00561     conn->inlock = mutex_create();
00562     conn->outlock = mutex_create();
00563     conn->claimed = 0;
00564 
00565     conn->outbuf = octstr_create("");
00566     conn->outbufpos = 0;
00567     conn->inbuf = octstr_create("");
00568     conn->inbufpos = 0;
00569 
00570     conn->fd = fd;
00571     conn->connected = yes;
00572     conn->read_eof = 0;
00573     conn->io_error = 0;
00574     conn->output_buffering = DEFAULT_OUTPUT_BUFFERING;
00575 
00576     conn->registered = NULL;
00577     conn->callback = NULL;
00578     conn->callback_data = NULL;
00579     conn->callback_data_destroyer = NULL;
00580     conn->listening_pollin = 0;
00581     conn->listening_pollout = 0;
00582 #ifdef HAVE_LIBSSL
00583     /*
00584      * do all the SSL magic for this connection
00585      */
00586     if (ssl) {
00587         conn->ssl = SSL_new(global_server_ssl_context);
00588         conn->peer_certificate = NULL;
00589 
00590         /* SSL_set_fd can fail, so check it */
00591         if (SSL_set_fd(conn->ssl, conn->fd) == 0) {
00592             /* SSL_set_fd failed, log error and return NULL */
00593             error(errno, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL));
00594             conn_destroy(conn);
00595             return NULL;
00596         }
00597         /* SSL_set_verify(conn->ssl, 0, NULL); */
00598 
00599         /* set read/write BIO layer to non-blocking mode */
00600         BIO_set_nbio(SSL_get_rbio(conn->ssl), 1);
00601         BIO_set_nbio(SSL_get_wbio(conn->ssl), 1);
00602 
00603         /* set accept state , SSL-Handshake will be handled transparent while SSL_[read|write] */
00604          SSL_set_accept_state(conn->ssl);
00605     } else {
00606         conn->ssl = NULL;
00607         conn->peer_certificate = NULL;
00608     }
00609 #endif /* HAVE_LIBSSL */
00610 
00611     return conn;
00612 }
00613 
00614 void conn_destroy(Connection *conn)
00615 {
00616     int ret;
00617 
00618     if (conn == NULL)
00619         return;
00620 
00621     /* No locking done here.  conn_destroy should not be called
00622      * if any thread might still be interested in the connection. */
00623 
00624     if (conn->registered) {
00625         fdset_unregister(conn->registered, conn->fd);
00626         /* call data destroyer if any */
00627         if (conn->callback_data != NULL && conn->callback_data_destroyer != NULL)
00628             conn->callback_data_destroyer(conn->callback_data);
00629     }
00630 
00631     if (conn->fd >= 0) {
00632         /* Try to flush any remaining data */
00633         unlocked_try_write(conn);
00634 
00635 #ifdef HAVE_LIBSSL
00636         if (conn->ssl != NULL) {
00637             SSL_smart_shutdown(conn->ssl);
00638             SSL_free(conn->ssl);
00639             if (conn->peer_certificate != NULL)
00640                 X509_free(conn->peer_certificate);
00641     }
00642 #endif /* HAVE_LIBSSL */
00643 
00644         ret = close(conn->fd);
00645         if (ret < 0)
00646             error(errno, "conn_destroy: error on close");
00647         conn->fd = -1;
00648     }
00649 
00650     octstr_destroy(conn->outbuf);
00651     octstr_destroy(conn->inbuf);
00652     mutex_destroy(conn->inlock);
00653     mutex_destroy(conn->outlock);
00654 
00655     gw_free(conn);
00656 }
00657 
00658 void conn_claim(Connection *conn)
00659 {
00660     gw_assert(conn != NULL);
00661 
00662     if (conn->claimed)
00663         panic(0, "Connection is being claimed twice!");
00664     conn->claimed = 1;
00665 #ifndef NO_GWASSERT
00666     conn->claiming_thread = gwthread_self();
00667 #endif
00668 }
00669 
00670 long conn_outbuf_len(Connection *conn)
00671 {
00672     long len;
00673 
00674     lock_out(conn);
00675     len = unlocked_outbuf_len(conn);
00676     unlock_out(conn);
00677 
00678     return len;
00679 }
00680 
00681 long conn_inbuf_len(Connection *conn)
00682 {
00683     long len;
00684 
00685     lock_in(conn);
00686     len = unlocked_inbuf_len(conn);
00687     unlock_in(conn);
00688 
00689     return len;
00690 }
00691 
00692 int conn_eof(Connection *conn)
00693 {
00694     int eof;
00695 
00696     lock_in(conn);
00697     eof = conn->read_eof;
00698     unlock_in(conn);
00699 
00700     return eof;
00701 }
00702 
00703 int conn_error(Connection *conn)
00704 {
00705     int err;
00706 
00707     lock_out(conn);
00708     lock_in(conn);
00709     err = conn->io_error;
00710     unlock_in(conn);
00711     unlock_out(conn);
00712 
00713     return err;
00714 }
00715 
00716 void conn_set_output_buffering(Connection *conn, unsigned int size)
00717 {
00718     lock_out(conn);
00719     conn->output_buffering = size;
00720     /* If the buffer size is smaller, we may have to write immediately. */
00721     unlocked_try_write(conn);
00722     unlock_out(conn);
00723 }
00724 
00725 static void poll_callback(int fd, int revents, void *data)
00726 {
00727     Connection *conn;
00728     int do_callback = 0;
00729 
00730     conn = data;
00731 
00732     if (conn == NULL) {
00733         error(0, "poll_callback called with NULL connection.");
00734         return;
00735     }
00736 
00737     if (conn->fd != fd) {
00738         error(0, "poll_callback called on wrong connection.");
00739         return;
00740     }
00741 
00742     /* Get result of nonblocking connect, before any reads and writes
00743      * we must check result (it must be handled in initial callback) */
00744     if (conn->connected == no) {
00745         if (conn->callback)
00746             conn->callback(conn, conn->callback_data);
00747         return;
00748     }
00749 
00750     /* If got POLLERR or POLHUP, then unregister the descriptor from the
00751      * fdset and set the error condition variable to let the upper layer
00752      * close and destroy the connection. */
00753     if (revents & (POLLERR|POLLHUP)) {
00754         lock_out(conn);
00755         lock_in(conn);
00756         if (conn->listening_pollin)
00757             unlocked_register_pollin(conn, 0);
00758         if (conn->listening_pollout)
00759             unlocked_register_pollout(conn, 0);
00760         conn->io_error = 1;
00761         unlock_in(conn);
00762         unlock_out(conn);
00763         do_callback = 1;
00764     }
00765 
00766     /* If unlocked_write manages to write all pending data, it will
00767      * tell the fdset to stop listening for POLLOUT. */
00768     if (revents & POLLOUT) {
00769         lock_out(conn);
00770         unlocked_write(conn);
00771         if (unlocked_outbuf_len(conn) == 0)
00772             do_callback = 1;
00773         unlock_out(conn);
00774     }
00775 
00776     /* We read only in unlocked_read in we received POLLIN, cause the 
00777      * descriptor is already broken and of no use anymore. */
00778     if (revents & POLLIN) {
00779         lock_in(conn);
00780         unlocked_read(conn);
00781         unlock_in(conn);
00782         do_callback = 1;
00783     }
00784 
00785     if (do_callback && conn->callback)
00786         conn->callback(conn, conn->callback_data);
00787 }
00788 
00789 int conn_register_real(Connection *conn, FDSet *fdset,
00790                   conn_callback_t callback, void *data, conn_callback_data_destroyer_t *data_destroyer)
00791 {
00792     int events;
00793     int result = 0;
00794 
00795     gw_assert(conn != NULL);
00796 
00797     if (conn->fd < 0)
00798         return -1;
00799 
00800     /* We need both locks if we want to update the registration
00801      * information. */
00802     lock_out(conn);
00803     lock_in(conn);
00804 
00805     if (conn->registered == fdset) {
00806         /* Re-registering.  Change only the callback info. */
00807         conn->callback = callback;
00808         /* call data destroyer if new data supplied */
00809         if (conn->callback_data != NULL && conn->callback_data != data && conn->callback_data_destroyer != NULL)
00810             conn->callback_data_destroyer(conn->callback_data);
00811         conn->callback_data = data;
00812         conn->callback_data_destroyer = data_destroyer;
00813         result = 0;
00814     } else if (conn->registered) {
00815         /* Already registered to a different fdset. */
00816         result = -1;
00817     } else {
00818         events = 0;
00819     /* For nonconnected socket we must lesten both directions */
00820         if (conn->connected == yes) {
00821             if (conn->read_eof == 0 && conn->io_error == 0)
00822                 events |= POLLIN;
00823             if (unlocked_outbuf_len(conn) > 0)
00824                 events |= POLLOUT;
00825         } else {
00826           events |= POLLIN | POLLOUT;
00827         }
00828 
00829         conn->registered = fdset;
00830         conn->callback = callback;
00831         conn->callback_data = data;
00832         conn->callback_data_destroyer = data_destroyer;
00833         conn->listening_pollin = (events & POLLIN) != 0;
00834         conn->listening_pollout = (events & POLLOUT) != 0;
00835         fdset_register(fdset, conn->fd, events, poll_callback, conn);
00836         result = 0;
00837     }
00838 
00839     unlock_in(conn);
00840     unlock_out(conn);
00841 
00842     return result;
00843 }
00844 
00845 void conn_unregister(Connection *conn)
00846 {
00847     FDSet *set = NULL;
00848     int fd = -1;
00849     void *data = NULL;
00850     conn_callback_data_destroyer_t *destroyer = NULL;
00851     
00852     gw_assert(conn != NULL);
00853 
00854     if (conn == NULL || conn->fd < 0)
00855         return;
00856 
00857     /* We need both locks to update the registration information */
00858     lock_out(conn);
00859     lock_in(conn);
00860 
00861     if (conn->registered) {
00862         set = conn->registered;
00863         fd = conn->fd;
00864         conn->registered = NULL;
00865         conn->callback = NULL;
00866         /*
00867          * remember and don't destroy data and data_destroyer because we
00868          * may be in callback right now. So destroy only after fdset_unregister
00869          * call which guarantee us we are not in callback anymore.
00870          */
00871         data = conn->callback_data;
00872         conn->callback_data = NULL;
00873         destroyer = conn->callback_data_destroyer;
00874         conn->callback_data_destroyer = NULL;
00875         conn->listening_pollin = 0;
00876         conn->listening_pollout = 0;
00877     }
00878 
00879     unlock_in(conn);
00880     unlock_out(conn);
00881 
00882     /* now unregister from FDSet */
00883     if (set != NULL)
00884         fdset_unregister(set, fd);
00885 
00886     /* ok we are not in callback anymore, destroy data if any */
00887     if (data != NULL && destroyer != NULL)
00888         destroyer(data);
00889 }
00890 
00891 int conn_wait(Connection *conn, double seconds)
00892 {
00893     int events;
00894     int ret;
00895     int fd;
00896 
00897     lock_out(conn);
00898 
00899     /* Try to write any data that might still be waiting to be sent */
00900     ret = unlocked_write(conn);
00901     if (ret < 0) {
00902         unlock_out(conn);
00903         return -1;
00904     }
00905     if (ret > 0) {
00906         /* We did something useful.  No need to poll or wait now. */
00907         unlock_out(conn);
00908         return 0;
00909     }
00910 
00911     fd = conn->fd;
00912 
00913     /* Normally, we block until there is more data available.  But
00914      * if any data still needs to be sent, we block until we can
00915      * send it (or there is more data available).  We always block
00916      * for reading, unless we know there is no more data coming.
00917      * (Because in that case, poll will keep reporting POLLIN to
00918      * signal the end of the file).  If the caller explicitly wants
00919      * to wait even though there is no data to write and we're at
00920      * end of file, then poll for new data anyway because the caller
00921      * apparently doesn't trust eof. */
00922     events = 0;
00923     if (unlocked_outbuf_len(conn) > 0)
00924         events |= POLLOUT;
00925     /* Don't keep the connection locked while we wait */
00926     unlock_out(conn);
00927 
00928     /* We need the in lock to query read_eof */
00929     lock_in(conn);
00930     if ((conn->read_eof == 0 && conn->io_error == 0) || events == 0)
00931         events |= POLLIN;
00932     unlock_in(conn);
00933 
00934     ret = gwthread_pollfd(fd, events, seconds);
00935     if (ret < 0) {
00936         if (errno == EINTR)
00937             return 0;
00938         error(0, "conn_wait: poll failed on fd %d:", fd);
00939         return -1;
00940     }
00941 
00942     if (ret == 0)
00943         return 1;
00944 
00945     if (ret & POLLNVAL) {
00946         error(0, "conn_wait: fd %d not open.", fd);
00947         return -1;
00948     }
00949 
00950     if (ret & (POLLERR | POLLHUP)) {
00951         /* Call unlocked_read to report the specific error,
00952          * and handle the results of the error.  We can't be
00953          * certain that the error still exists, because we
00954          * released the lock for a while. */
00955         lock_in(conn);
00956         unlocked_read(conn);
00957         unlock_in(conn);
00958         return -1;
00959     }
00960 
00961     /* If POLLOUT is on, then we must have wanted
00962      * to write something. */
00963     if (ret & POLLOUT) {
00964         lock_out(conn);
00965         unlocked_write(conn);
00966         unlock_out(conn);
00967     }
00968 
00969     /* Since we normally select for reading, we must
00970      * try to read here.  Otherwise, if the caller loops
00971      * around conn_wait without making conn_read* calls
00972      * in between, we will keep polling this same data. */
00973     if (ret & POLLIN) {
00974         lock_in(conn);
00975         unlocked_read(conn);
00976         unlock_in(conn);
00977     }
00978 
00979     return 0;
00980 }
00981 
00982 int conn_flush(Connection *conn)
00983 {
00984     int ret;
00985     int revents;
00986     int fd;
00987 
00988     lock_out(conn);
00989     ret = unlocked_write(conn);
00990     if (ret < 0) {
00991         unlock_out(conn);
00992         return -1;
00993     }
00994 
00995     while (unlocked_outbuf_len(conn) != 0) {
00996         fd = conn->fd;
00997 
00998         unlock_out(conn);
00999         revents = gwthread_pollfd(fd, POLLOUT, -1.0);
01000 
01001         /* Note: Make sure we have the "out" lock when
01002          * going through the loop again, because the 
01003          * loop condition needs it. */
01004 
01005         if (revents < 0) {
01006             if (errno == EINTR)
01007                 return 1;
01008             error(0, "conn_flush: poll failed on fd %d:", fd);
01009             return -1;
01010         }
01011 
01012         if (revents == 0) {
01013             /* We were woken up */
01014             return 1;
01015         }
01016 
01017         if (revents & POLLNVAL) {
01018             error(0, "conn_flush: fd %d not open.", fd);
01019             return -1;
01020         }
01021 
01022         lock_out(conn);
01023 
01024         if (revents & (POLLOUT | POLLERR | POLLHUP)) {
01025             ret = unlocked_write(conn);
01026             if (ret < 0) {
01027                 unlock_out(conn);
01028                 return -1;
01029             }
01030         }
01031     }
01032 
01033     unlock_out(conn);
01034 
01035     return 0;
01036 }
01037 
01038 int conn_write(Connection *conn, Octstr *data)
01039 {
01040     int ret;
01041 
01042     lock_out(conn);
01043     octstr_append(conn->outbuf, data);
01044     ret = unlocked_try_write(conn);
01045     unlock_out(conn);
01046 
01047     return ret;
01048 }
01049 
01050 int conn_write_data(Connection *conn, unsigned char *data, long length)
01051 {
01052     int ret;
01053 
01054     lock_out(conn);
01055     octstr_append_data(conn->outbuf, data, length);
01056     ret = unlocked_try_write(conn);
01057     unlock_out(conn);
01058 
01059     return ret;
01060 }
01061 
01062 int conn_write_withlen(Connection *conn, Octstr *data)
01063 {
01064     int ret;
01065     unsigned char lengthbuf[4];
01066 
01067     encode_network_long(lengthbuf, octstr_len(data));
01068     lock_out(conn);
01069     octstr_append_data(conn->outbuf, lengthbuf, 4);
01070     octstr_append(conn->outbuf, data);
01071     ret = unlocked_try_write(conn);
01072     unlock_out(conn);
01073 
01074     return ret;
01075 }
01076 
01077 Octstr *conn_read_everything(Connection *conn)
01078 {
01079     Octstr *result = NULL;
01080 
01081     lock_in(conn);
01082     if (unlocked_inbuf_len(conn) == 0) {
01083         unlocked_read(conn);
01084         if (unlocked_inbuf_len(conn) == 0) {
01085             unlock_in(conn);
01086             return NULL;
01087         }
01088     }
01089 
01090     result = unlocked_get(conn, unlocked_inbuf_len(conn));
01091     gw_claim_area(result);
01092     unlock_in(conn);
01093 
01094     return result;
01095 }
01096 
01097 Octstr *conn_read_fixed(Connection *conn, long length)
01098 {
01099     Octstr *result = NULL;
01100 
01101     if (length < 1)
01102         return NULL;
01103 
01104     /* See if the data is already available.  If not, try a read(),
01105      * then see if we have enough data after that.  If not, give up. */
01106     lock_in(conn);
01107     if (unlocked_inbuf_len(conn) < length) {
01108         unlocked_read(conn);
01109         if (unlocked_inbuf_len(conn) < length) {
01110             unlock_in(conn);
01111             return NULL;
01112         }
01113     }
01114     result = unlocked_get(conn, length);
01115     gw_claim_area(result);
01116     unlock_in(conn);
01117 
01118     return result;
01119 }
01120 
01121 Octstr *conn_read_line(Connection *conn)
01122 {
01123     Octstr *result = NULL;
01124     long pos;
01125 
01126     lock_in(conn);
01127     /* 10 is the code for linefeed.  We don't rely on \n because that
01128      * might be a different value on some (strange) systems, and
01129      * we are reading from a network connection. */
01130     pos = octstr_search_char(conn->inbuf, 10, conn->inbufpos);
01131     if (pos < 0) {
01132         unlocked_read(conn);
01133         pos = octstr_search_char(conn->inbuf, 10, conn->inbufpos);
01134         if (pos < 0) {
01135             unlock_in(conn);
01136             return NULL;
01137         }
01138     }
01139 
01140     result = unlocked_get(conn, pos - conn->inbufpos);
01141     gw_claim_area(result);
01142 
01143     /* Skip the LF, which we left in the buffer */
01144     conn->inbufpos++;
01145 
01146     /* If the line was terminated with CR LF, we have to remove
01147      * the CR from the result. */
01148     if (octstr_len(result) > 0 &&
01149         octstr_get_char(result, octstr_len(result) - 1) == 13)
01150         octstr_delete(result, octstr_len(result) - 1, 1);
01151 
01152     unlock_in(conn);
01153     return result;
01154 }
01155 
01156 Octstr *conn_read_withlen(Connection *conn)
01157 {
01158     Octstr *result = NULL;
01159     unsigned char lengthbuf[4];
01160     long length = 0; /* for compiler please */
01161     int try, retry;
01162 
01163     lock_in(conn);
01164 
01165     for (try = 1; try <= 2; try++) {
01166         if (try > 1)
01167             unlocked_read(conn);
01168 
01169         do {
01170             retry = 0;
01171             /* First get the length. */
01172             if (unlocked_inbuf_len(conn) < 4)
01173                 continue;
01174 
01175             octstr_get_many_chars(lengthbuf, conn->inbuf, conn->inbufpos, 4);
01176             length = decode_network_long(lengthbuf);
01177 
01178             if (length < 0) {
01179                 warning(0, "conn_read_withlen: got negative length, skipping");
01180                 conn->inbufpos += 4;
01181                 retry = 1;
01182              }
01183         } while(retry == 1);
01184 
01185         /* Then get the data. */
01186         if (unlocked_inbuf_len(conn) - 4 < length)
01187             continue;
01188 
01189         conn->inbufpos += 4;
01190         result = unlocked_get(conn, length);
01191         gw_claim_area(result);
01192         break;
01193     }
01194 
01195     unlock_in(conn);
01196     return result;
01197 }
01198 
01199 Octstr *conn_read_packet(Connection *conn, int startmark, int endmark)
01200 {
01201     int startpos, endpos;
01202     Octstr *result = NULL;
01203     int try;
01204 
01205     lock_in(conn);
01206 
01207     for (try = 1; try <= 2; try++) {
01208         if (try > 1)
01209             unlocked_read(conn);
01210 
01211         /* Find startmark, and discard everything up to it */
01212         startpos = octstr_search_char(conn->inbuf, startmark, conn->inbufpos);
01213         if (startpos < 0) {
01214             conn->inbufpos = octstr_len(conn->inbuf);
01215             continue;
01216         } else {
01217             conn->inbufpos = startpos;
01218         }
01219 
01220         /* Find first endmark after startmark */
01221         endpos = octstr_search_char(conn->inbuf, endmark, conn->inbufpos);
01222         if (endpos < 0)
01223             continue;
01224 
01225         result = unlocked_get(conn, endpos - startpos + 1);
01226         gw_claim_area(result);
01227         break;
01228     }
01229 
01230     unlock_in(conn);
01231     return result;
01232 }
01233 
01234 #ifdef HAVE_LIBSSL
01235 X509 *conn_get_peer_certificate(Connection *conn) 
01236 {
01237     /* Don't know if it needed to be locked , but better safe as crash */
01238     lock_out(conn);
01239     lock_in(conn);
01240     if (conn->peer_certificate == NULL && conn->ssl != NULL)
01241         conn->peer_certificate = SSL_get_peer_certificate(conn->ssl);
01242     unlock_in(conn);
01243     unlock_out(conn);
01244     
01245     return conn->peer_certificate;
01246 }
01247 
01248 /*
01249  * XXX Alex decalred the RSA callback routine static and now we're getting 
01250  * warning messages for our automatic compilation tests. So we are commenting
01251  * the function out to avoid the warnings.
01252  *
01253 
01254 static RSA *tmp_rsa_callback(SSL *ssl, int export, int key_len)
01255 {
01256     static RSA *rsa = NULL;
01257     debug("gwlib.http", 0, "SSL: Generating new RSA key (export=%d, keylen=%d)", export, key_len);
01258     if (export) {
01259        rsa = RSA_generate_key(key_len, RSA_F4, NULL, NULL);
01260     } else {
01261        debug("gwlib.http", 0, "SSL: Export not set");
01262     }
01263     return rsa;
01264 }
01265 */
01266 
01267 static Mutex **ssl_static_locks = NULL;
01268 
01269 /* the call-back function for the openssl crypto thread locking */
01270 static void openssl_locking_function(int mode, int n, const char *file, int line)
01271 {
01272     if (mode & CRYPTO_LOCK)
01273         mutex_lock(ssl_static_locks[n-1]);
01274     else
01275         mutex_unlock(ssl_static_locks[n-1]);
01276 }
01277 
01278 void openssl_init_locks(void)
01279 {
01280     int c, maxlocks = CRYPTO_num_locks();
01281 
01282     gw_assert(ssl_static_locks == NULL);
01283 
01284     ssl_static_locks = gw_malloc(sizeof(Mutex *) * maxlocks);
01285     for (c = 0; c < maxlocks; c++)
01286         ssl_static_locks[c] = mutex_create();
01287 
01288     /* after the mutexes have been created, apply the call-back to it */
01289     CRYPTO_set_locking_callback(openssl_locking_function);
01290     CRYPTO_set_id_callback((CRYPTO_CALLBACK_PTR)gwthread_self);
01291 }
01292 
01293 void openssl_shutdown_locks(void)
01294 {
01295     int c, maxlocks = CRYPTO_num_locks();
01296 
01297     gw_assert(ssl_static_locks != NULL);
01298 
01299     /* remove call-back from the locks */
01300     CRYPTO_set_locking_callback(NULL);
01301 
01302     for (c = 0; c < maxlocks; c++) 
01303         mutex_destroy(ssl_static_locks[c]);
01304 
01305     gw_free(ssl_static_locks);
01306     ssl_static_locks = NULL;
01307 }
01308 
01309 void conn_init_ssl(void)
01310 {
01311     SSL_library_init();
01312     SSL_load_error_strings();
01313     global_ssl_context = SSL_CTX_new(SSLv23_client_method());
01314     SSL_CTX_set_mode(global_ssl_context, 
01315         SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
01316 }
01317 
01318 void server_ssl_init(void) 
01319 {
01320     SSLeay_add_ssl_algorithms();
01321     SSL_load_error_strings();
01322     global_server_ssl_context = SSL_CTX_new(SSLv23_server_method());
01323     SSL_CTX_set_mode(global_server_ssl_context, 
01324         SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
01325     if (!SSL_CTX_set_default_verify_paths(global_server_ssl_context)) {
01326        panic(0, "can not set default path for server");
01327     }
01328 }
01329 
01330 void conn_shutdown_ssl(void)
01331 {
01332     if (global_ssl_context)
01333         SSL_CTX_free(global_ssl_context);
01334     
01335     ERR_free_strings();
01336     EVP_cleanup();
01337 }
01338 
01339 void server_shutdown_ssl(void)
01340 {
01341     if (global_server_ssl_context)
01342         SSL_CTX_free(global_server_ssl_context);
01343 
01344     ERR_free_strings();
01345     EVP_cleanup();
01346 }
01347 
01348 void use_global_client_certkey_file(Octstr *certkeyfile)
01349 { 
01350     SSL_CTX_use_certificate_file(global_ssl_context, 
01351                                  octstr_get_cstr(certkeyfile), 
01352                                  SSL_FILETYPE_PEM);
01353     SSL_CTX_use_PrivateKey_file(global_ssl_context,
01354                                 octstr_get_cstr(certkeyfile),
01355                                 SSL_FILETYPE_PEM);
01356     if (SSL_CTX_check_private_key(global_ssl_context) != 1)
01357         panic(0, "reading global client certificate file `%s', the certificate "
01358           "isn't consistent with the private key (or failed reading the file)", 
01359               octstr_get_cstr(certkeyfile));
01360     info(0, "Using global SSL certificate and key from file `%s'",
01361          octstr_get_cstr(certkeyfile));
01362 }
01363 
01364 void use_global_server_certkey_file(Octstr *certfile, Octstr *keyfile) 
01365 {
01366     SSL_CTX_use_certificate_file(global_server_ssl_context, 
01367                                   octstr_get_cstr(certfile), 
01368                                   SSL_FILETYPE_PEM);
01369     SSL_CTX_use_PrivateKey_file(global_server_ssl_context,
01370                                  octstr_get_cstr(keyfile),
01371                                  SSL_FILETYPE_PEM);
01372     if (SSL_CTX_check_private_key(global_server_ssl_context) != 1) {
01373         error(0, "SSL: %s", ERR_error_string(ERR_get_error(), NULL));
01374         panic(0, "reading global server certificate file %s, the certificate \
01375                   isn't consistent with the private key in file %s \
01376                   (or failed reading the file)", 
01377                   octstr_get_cstr(certfile), octstr_get_cstr(keyfile));
01378     }
01379     info(0, "Using global server SSL certificate from file `%s'", octstr_get_cstr(certfile));
01380     info(0, "Using global server SSL key from file `%s'", octstr_get_cstr(keyfile));
01381 }
01382 
01383 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
01384 {
01385     char    subject[256];
01386     char    issuer [256];
01387     char   *status;
01388 
01389     X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), subject, sizeof(subject));
01390     X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), issuer, sizeof (issuer));
01391 
01392     status = preverify_ok ? "Accepting" : "Rejecting";
01393     
01394     info(0, "%s certificate for \"%s\" signed by \"%s\"", status, subject, issuer);
01395     
01396     return preverify_ok;
01397 }
01398 
01399 void use_global_trusted_ca_file(Octstr *ssl_trusted_ca_file)
01400 {
01401     if (ssl_trusted_ca_file != NULL) {
01402     if (!SSL_CTX_load_verify_locations(global_ssl_context,
01403                        octstr_get_cstr(ssl_trusted_ca_file),
01404                        NULL)) {
01405         panic(0, "Failed to load SSL CA file: %s", octstr_get_cstr(ssl_trusted_ca_file));
01406     } else {
01407         info(0, "Using CA root certificates from file %s",
01408          octstr_get_cstr(ssl_trusted_ca_file));
01409         SSL_CTX_set_verify(global_ssl_context,
01410                    SSL_VERIFY_PEER,
01411                    verify_callback);
01412     }
01413     
01414     } else {
01415     SSL_CTX_set_verify(global_ssl_context,
01416                SSL_VERIFY_NONE,
01417                NULL);
01418     }
01419 }
01420 
01421 void conn_config_ssl (CfgGroup *grp)
01422 {
01423     Octstr *ssl_client_certkey_file = NULL;
01424     Octstr *ssl_server_cert_file    = NULL;
01425     Octstr *ssl_server_key_file     = NULL;
01426     Octstr *ssl_trusted_ca_file     = NULL;
01427 
01428     /*
01429      * check if SSL is desired for HTTP servers and then
01430      * load SSL client and SSL server public certificates 
01431      * and private keys
01432      */    
01433     ssl_client_certkey_file = cfg_get(grp, octstr_imm("ssl-client-certkey-file"));
01434     if (ssl_client_certkey_file != NULL) 
01435         use_global_client_certkey_file(ssl_client_certkey_file);
01436     
01437     ssl_server_cert_file = cfg_get(grp, octstr_imm("ssl-server-cert-file"));
01438     ssl_server_key_file = cfg_get(grp, octstr_imm("ssl-server-key-file"));
01439     
01440     if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) {
01441         use_global_server_certkey_file(ssl_server_cert_file, 
01442                        ssl_server_key_file);
01443     }
01444 
01445     ssl_trusted_ca_file = cfg_get(grp, octstr_imm("ssl-trusted-ca-file"));
01446     
01447     use_global_trusted_ca_file(ssl_trusted_ca_file);
01448 
01449     octstr_destroy(ssl_client_certkey_file);
01450     octstr_destroy(ssl_server_cert_file);
01451     octstr_destroy(ssl_server_key_file);
01452     octstr_destroy(ssl_trusted_ca_file);
01453 }
01454 
01455 SSL *conn_get_ssl(Connection *conn)
01456 {
01457     if (conn != NULL)
01458         return conn->ssl;
01459     else 
01460         return NULL;
01461 }
01462 
01463 #else
01464 
01465 void conn_config_ssl (CfgGroup *grp)
01466 {
01467     info(0, "SSL not supported, no SSL initialization done.");
01468 }
01469 #endif /* HAVE_LIBSSL */
01470 
01471 int conn_get_id(Connection *conn) {
01472     if(conn == NULL)
01473     return 0;
01474     else
01475     return conn->fd;
01476 }
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.