00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
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
00091
00092 typedef unsigned long (*CRYPTO_CALLBACK_PTR)(void);
00093
00094
00095
00096
00097
00098
00099
00100
00101 #define DEFAULT_OUTPUT_BUFFERING 0
00102 #define SSL_CONN_TIMEOUT 30
00103
00104 struct Connection
00105 {
00106
00107
00108
00109 Mutex *inlock;
00110 Mutex *outlock;
00111 volatile sig_atomic_t claimed;
00112 #ifndef NO_GWASSERT
00113 long claiming_thread;
00114 #endif
00115
00116
00117 int fd;
00118
00119
00120 enum {yes,no} connected;
00121
00122
00123 Octstr *outbuf;
00124 long outbufpos;
00125
00126
00127
00128 unsigned int output_buffering;
00129
00130
00131 Octstr *inbuf;
00132 long inbufpos;
00133
00134 int read_eof;
00135 int io_error;
00136
00137
00138
00139 FDSet *registered;
00140 conn_callback_t *callback;
00141 void *callback_data;
00142 conn_callback_data_destroyer_t *callback_data_destroyer;
00143
00144 int listening_pollin;
00145
00146 int listening_pollout;
00147
00148 #ifdef HAVE_LIBSSL
00149 SSL *ssl;
00150 X509 *peer_certificate;
00151 #endif
00152 };
00153
00154 static void unlocked_register_pollin(Connection *conn, int onoff);
00155 static void unlocked_register_pollout(Connection *conn, int onoff);
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
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
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
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
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
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
00220 static long inline unlocked_outbuf_len(Connection *conn)
00221 {
00222 return octstr_len(conn->outbuf) - conn->outbufpos;
00223 }
00224
00225
00226 static long inline unlocked_inbuf_len(Connection *conn)
00227 {
00228 return octstr_len(conn->inbuf) - conn->inbufpos;
00229 }
00230
00231
00232
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;
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
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
00267
00268
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
00281
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
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
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;
00328 error(errno, "SSL read failed: OpenSSL error %d: %s",
00329 SSL_error, ERR_error_string(SSL_error, NULL));
00330 }
00331 else
00332 #endif
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
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
00360
00361
00362
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
00370 conn->listening_pollin = 1;
00371 fdset_listen(conn->registered, conn->fd, POLLIN, POLLIN);
00372 } else if (onoff == 0 && conn->listening_pollin) {
00373
00374 conn->listening_pollin = 0;
00375 fdset_listen(conn->registered, conn->fd, POLLIN, 0);
00376 }
00377 }
00378
00379
00380
00381
00382
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
00390 conn->listening_pollout = 1;
00391 fdset_listen(conn->registered, conn->fd, POLLOUT, POLLOUT);
00392 } else if (onoff == 0 && conn->listening_pollout) {
00393
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
00406
00407
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
00425 if (SSL_set_fd(ret->ssl, ret->fd) == 0) {
00426
00427 error(errno, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL));
00428 return -1;
00429 }
00430
00431
00432
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
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
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
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
00551
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
00585
00586 if (ssl) {
00587 conn->ssl = SSL_new(global_server_ssl_context);
00588 conn->peer_certificate = NULL;
00589
00590
00591 if (SSL_set_fd(conn->ssl, conn->fd) == 0) {
00592
00593 error(errno, "SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL));
00594 conn_destroy(conn);
00595 return NULL;
00596 }
00597
00598
00599
00600 BIO_set_nbio(SSL_get_rbio(conn->ssl), 1);
00601 BIO_set_nbio(SSL_get_wbio(conn->ssl), 1);
00602
00603
00604 SSL_set_accept_state(conn->ssl);
00605 } else {
00606 conn->ssl = NULL;
00607 conn->peer_certificate = NULL;
00608 }
00609 #endif
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
00622
00623
00624 if (conn->registered) {
00625 fdset_unregister(conn->registered, conn->fd);
00626
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
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
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
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
00743
00744 if (conn->connected == no) {
00745 if (conn->callback)
00746 conn->callback(conn, conn->callback_data);
00747 return;
00748 }
00749
00750
00751
00752
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
00767
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
00777
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
00801
00802 lock_out(conn);
00803 lock_in(conn);
00804
00805 if (conn->registered == fdset) {
00806
00807 conn->callback = callback;
00808
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
00816 result = -1;
00817 } else {
00818 events = 0;
00819
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
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
00868
00869
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
00883 if (set != NULL)
00884 fdset_unregister(set, fd);
00885
00886
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
00900 ret = unlocked_write(conn);
00901 if (ret < 0) {
00902 unlock_out(conn);
00903 return -1;
00904 }
00905 if (ret > 0) {
00906
00907 unlock_out(conn);
00908 return 0;
00909 }
00910
00911 fd = conn->fd;
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922 events = 0;
00923 if (unlocked_outbuf_len(conn) > 0)
00924 events |= POLLOUT;
00925
00926 unlock_out(conn);
00927
00928
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
00952
00953
00954
00955 lock_in(conn);
00956 unlocked_read(conn);
00957 unlock_in(conn);
00958 return -1;
00959 }
00960
00961
00962
00963 if (ret & POLLOUT) {
00964 lock_out(conn);
00965 unlocked_write(conn);
00966 unlock_out(conn);
00967 }
00968
00969
00970
00971
00972
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
01002
01003
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
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
01105
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
01128
01129
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
01144 conn->inbufpos++;
01145
01146
01147
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;
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
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
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
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
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
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
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267 static Mutex **ssl_static_locks = NULL;
01268
01269
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
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
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
01430
01431
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
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.