78 #include <sys/types.h> 79 #include <sys/socket.h> 85 #include <openssl/ssl.h> 86 #include <openssl/err.h> 87 #include <openssl/conf.h> 88 #include <openssl/engine.h> 90 static SSL_CTX *global_ssl_context = NULL;
91 static SSL_CTX *global_server_ssl_context = NULL;
103 #define DEFAULT_OUTPUT_BUFFERING 0 104 #define SSL_CONN_TIMEOUT 30 152 X509 *peer_certificate;
168 #define unlock_in(conn) unlock_in_real(conn, __FILE__, __LINE__, __func__) 169 #define unlock_out(conn) unlock_out_real(conn, __FILE__, __LINE__, __func__) 189 panic(0,
"%s:%ld: %s: Mutex unlock failed. " 190 "(Called from %s:%ld:%s.)",
191 __FILE__, (
long) __LINE__, __func__,
192 file, (
long) line, func);
214 panic(0,
"%s:%ld: %s: Mutex unlock failed. " 215 "(Called from %s:%ld:%s.)",
216 __FILE__, (
long) __LINE__, __func__,
217 file, (
long) line, func);
240 if (conn->ssl != NULL) {
242 ret = SSL_write(conn->ssl,
247 int SSL_error = SSL_get_error(conn->ssl, ret);
249 if (SSL_error == SSL_ERROR_WANT_READ || SSL_error == SSL_ERROR_WANT_WRITE) {
252 error(errno,
"SSL write failed: OpenSSL error %d: %s",
253 SSL_error, ERR_error_string(SSL_error, NULL));
254 if (SSL_error == SSL_ERROR_SSL) {
256 while ((err = ERR_get_error()) != 0)
257 error(0,
"SSL %s", ERR_error_string(err, NULL));
312 unsigned char buf[4096];
321 if (conn->ssl != NULL) {
327 len = SSL_read(conn->ssl, buf,
sizeof(buf));
328 }
while (len > 0 && SSL_pending(conn->ssl) > 0);
331 len = read(conn->
fd, buf,
sizeof(buf));
334 if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
338 int SSL_error = SSL_get_error(conn->ssl, len);
339 if (SSL_error == SSL_ERROR_WANT_WRITE || SSL_error == SSL_ERROR_WANT_READ)
341 error(errno,
"SSL read failed: OpenSSL error %d: %s",
342 SSL_error, ERR_error_string(SSL_error, NULL));
346 error(errno,
"Error reading from fd %d:", conn->
fd);
351 }
else if (len == 0) {
415 ret->ssl = SSL_new(global_ssl_context);
424 if (certkeyfile != NULL) {
429 if (SSL_check_private_key(ret->ssl) != 1) {
430 error(0,
"conn_open_ssl: private key isn't consistent with the " 431 "certificate from file %s (or failed reading the file)",
438 if (SSL_set_fd(ret->ssl, ret->
fd) == 0) {
440 error(errno,
"SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL));
450 BIO_set_nbio(SSL_get_rbio(ret->ssl), 1);
451 BIO_set_nbio(SSL_get_wbio(ret->ssl), 1);
453 SSL_set_connect_state(ret->ssl);
468 if (conn_init_client_ssl(ret, certkeyfile) == -1) {
486 if (conn_init_client_ssl(ret, certkeyfile) == -1) {
536 if (getsockopt(conn->
fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
573 conn = gw_malloc(
sizeof(*conn));
600 conn->ssl = SSL_new(global_server_ssl_context);
601 conn->peer_certificate = NULL;
604 if (SSL_set_fd(conn->ssl, conn->
fd) == 0) {
606 error(errno,
"SSL: OpenSSL: %.256s", ERR_error_string(ERR_get_error(), NULL));
613 BIO_set_nbio(SSL_get_rbio(conn->ssl), 1);
614 BIO_set_nbio(SSL_get_wbio(conn->ssl), 1);
617 SSL_set_accept_state(conn->ssl);
620 conn->peer_certificate = NULL;
649 if (conn->ssl != NULL) {
650 SSL_smart_shutdown(conn->ssl);
652 if (conn->peer_certificate != NULL)
653 X509_free(conn->peer_certificate);
657 ret = close(conn->
fd);
659 error(errno,
"conn_destroy: error on close");
676 panic(0,
"Connection is being claimed twice!");
746 error(0,
"poll_callback called with NULL connection.");
750 if (conn->
fd != fd) {
751 error(0,
"poll_callback called on wrong connection.");
867 if (conn == NULL || conn->
fd < 0)
900 if (data != NULL && destroyer != NULL)
951 error(0,
"conn_wait: poll failed on fd %d:", fd);
959 error(0,
"conn_wait: fd %d not open.", fd);
1021 error(0,
"conn_flush: poll failed on fd %d:", fd);
1031 error(0,
"conn_flush: fd %d not open.", fd);
1078 unsigned char lengthbuf[4];
1104 gw_claim_area(result);
1128 gw_claim_area(result);
1154 gw_claim_area(result);
1172 unsigned char lengthbuf[4];
1178 for (
try = 1;
try <= 2;
try++) {
1192 warning(0,
"conn_read_withlen: got negative length, skipping");
1197 }
while (retry == 1);
1206 gw_claim_area(result);
1216 int startpos, endpos;
1222 for (
try = 1;
try <= 2;
try++) {
1245 gw_claim_area(result);
1254 X509 *conn_get_peer_certificate(
Connection *conn)
1259 if (conn->peer_certificate == NULL && conn->ssl != NULL)
1260 conn->peer_certificate = SSL_get_peer_certificate(conn->ssl);
1264 return conn->peer_certificate;
1286 #if OPENSSL_VERSION_NUMBER < 0x10100000L 1288 static Mutex **ssl_static_locks = NULL;
1291 static void openssl_locking_function(
int mode,
int n,
const char *
file,
int line)
1293 if (mode & CRYPTO_LOCK)
1299 void openssl_init_locks(
void)
1301 int c, maxlocks = CRYPTO_num_locks();
1305 ssl_static_locks = gw_malloc(
sizeof(
Mutex *) * maxlocks);
1306 for (c = 0; c < maxlocks; c++)
1310 CRYPTO_set_locking_callback(openssl_locking_function);
1314 void openssl_shutdown_locks(
void)
1316 int c, maxlocks = CRYPTO_num_locks();
1321 CRYPTO_set_locking_callback(NULL);
1323 for (c = 0; c < maxlocks; c++)
1326 gw_free(ssl_static_locks);
1327 ssl_static_locks = NULL;
1332 void conn_init_ssl(
void)
1334 #if OPENSSL_VERSION_NUMBER < 0x10100000L 1335 openssl_init_locks();
1339 SSL_load_error_strings();
1340 global_ssl_context = SSL_CTX_new(SSLv23_client_method());
1341 SSL_CTX_set_mode(global_ssl_context,
1342 SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1345 void server_ssl_init(
void)
1347 SSLeay_add_ssl_algorithms();
1348 SSL_load_error_strings();
1349 global_server_ssl_context = SSL_CTX_new(SSLv23_server_method());
1350 SSL_CTX_set_mode(global_server_ssl_context,
1351 SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1352 if (!SSL_CTX_set_default_verify_paths(global_server_ssl_context)) {
1353 panic(0,
"can not set default path for server");
1357 void conn_shutdown_ssl(
void)
1359 #if OPENSSL_VERSION_NUMBER < 0x10100000L 1360 openssl_shutdown_locks();
1363 if (global_ssl_context)
1364 SSL_CTX_free(global_ssl_context);
1366 CONF_modules_free();
1367 ERR_remove_state(0);
1369 CONF_modules_unload(1);
1372 CRYPTO_cleanup_all_ex_data();
1375 void server_shutdown_ssl(
void)
1377 if (global_server_ssl_context)
1378 SSL_CTX_free(global_server_ssl_context);
1380 CONF_modules_free();
1381 ERR_remove_state(0);
1383 CONF_modules_unload(1);
1386 CRYPTO_cleanup_all_ex_data();
1389 void conn_use_global_client_certkey_file(
Octstr *certkeyfile)
1391 SSL_CTX_use_certificate_chain_file(global_ssl_context,
1393 SSL_CTX_use_PrivateKey_file(global_ssl_context,
1396 if (SSL_CTX_check_private_key(global_ssl_context) != 1)
1397 panic(0,
"reading global client certificate file `%s', the certificate " 1398 "isn't consistent with the private key (or failed reading the file)",
1400 info(0,
"Using global SSL certificate and key from file `%s'",
1404 void conn_use_global_server_certkey_file(
Octstr *certfile,
Octstr *keyfile)
1406 SSL_CTX_use_certificate_chain_file(global_server_ssl_context,
1408 SSL_CTX_use_PrivateKey_file(global_server_ssl_context,
1411 if (SSL_CTX_check_private_key(global_server_ssl_context) != 1) {
1412 error(0,
"SSL: %s", ERR_error_string(ERR_get_error(), NULL));
1413 panic(0,
"reading global server certificate file %s, the certificate \ 1414 isn't consistent with the private key in file %s \ 1415 (or failed reading the file)",
1422 void conn_use_global_client_cipher_list(
Octstr *cipher)
1424 if (SSL_CTX_set_cipher_list(global_ssl_context,
octstr_get_cstr(cipher)) != 1) {
1425 error(0,
"SSL: %s", ERR_error_string(ERR_get_error(), NULL));
1426 SSL_CTX_free(global_ssl_context);
1427 panic(0,
"cipher list <%s> contains no supported ciphers!",
1432 void conn_use_global_server_cipher_list(
Octstr *cipher)
1434 if (SSL_CTX_set_cipher_list(global_server_ssl_context,
octstr_get_cstr(cipher)) != 1) {
1435 error(0,
"SSL: %s", ERR_error_string(ERR_get_error(), NULL));
1436 SSL_CTX_free(global_server_ssl_context);
1437 panic(0,
"cipher list <%s> contains no supported ciphers!",
1442 static int verify_callback(
int preverify_ok, X509_STORE_CTX *ctx)
1449 #if OPENSSL_VERSION_NUMBER < 0x10100000L 1450 curr_cert = ctx->current_cert;
1451 X509_NAME_oneline(X509_get_subject_name(curr_cert), subject,
sizeof(subject));
1452 X509_NAME_oneline(X509_get_issuer_name(curr_cert), issuer,
sizeof (issuer));
1454 curr_cert = X509_STORE_CTX_get_current_cert(ctx);
1455 X509_NAME_oneline(X509_get_subject_name(curr_cert), subject,
sizeof(subject));
1456 X509_NAME_oneline(X509_get_issuer_name(curr_cert), issuer,
sizeof (issuer));
1459 status = preverify_ok ?
"Accepting" :
"Rejecting";
1461 info(0,
"%s certificate for \"%s\" signed by \"%s\"",
status, subject, issuer);
1463 return preverify_ok;
1466 void conn_use_global_trusted_ca_file(
Octstr *ssl_trusted_ca_file)
1468 if (ssl_trusted_ca_file != NULL) {
1469 if (!SSL_CTX_load_verify_locations(global_ssl_context,
1474 info(0,
"Using CA root certificates from file %s",
1476 SSL_CTX_set_verify(global_ssl_context,
1482 SSL_CTX_set_verify(global_ssl_context,
1491 Octstr *ssl_server_cert_file = NULL;
1492 Octstr *ssl_server_key_file = NULL;
1493 Octstr *ssl_trusted_ca_file = NULL;
1494 Octstr *ssl_client_cipher_list = NULL;
1495 Octstr *ssl_server_cipher_list = NULL;
1509 if (ssl_server_cert_file != NULL && ssl_server_key_file != NULL) {
1510 conn_use_global_server_certkey_file(ssl_server_cert_file,
1511 ssl_server_key_file);
1516 conn_use_global_trusted_ca_file(ssl_trusted_ca_file);
1521 if ((ssl_client_cipher_list =
cfg_get(grp,
octstr_imm(
"ssl-client-cipher-list"))) != NULL) {
1522 conn_use_global_client_cipher_list(ssl_client_cipher_list);
1524 if ((ssl_server_cipher_list =
cfg_get(grp,
octstr_imm(
"ssl-server-cipher-list"))) != NULL) {
1525 conn_use_global_server_cipher_list(ssl_server_cipher_list);
1548 info(0,
"SSL not supported, no SSL initialization done.");
Octstr * conn_read_line(Connection *conn)
void error(int err, const char *fmt,...)
void info(int err, const char *fmt,...)
int socket_set_blocking(int fd, int blocking)
Connection * conn_open_tcp(Octstr *host, int port, Octstr *our_host)
void octstr_append_data(Octstr *ostr, const char *data, long len)
static int unlocked_try_write(Connection *conn)
void fdset_listen(FDSet *set, int fd, int mask, int events)
conn_callback_t * callback
gw_assert(wtls_machine->packet_to_send !=NULL)
static void startmark(unsigned char *p, long number)
void encode_network_long(unsigned char *data, unsigned long value)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
unsigned int output_buffering
int conn_is_connected(Connection *conn)
static void unlocked_register_pollin(Connection *conn, int onoff)
static void unlocked_register_pollout(Connection *conn, int onoff)
Connection * conn_open_tcp_nb(Octstr *host, int port, Octstr *our_host)
static void endmark(unsigned char *p, size_t size)
#define cfg_get(grp, varname)
static long unlocked_outbuf_len(Connection *conn)
int conn_write_data(Connection *conn, unsigned char *data, long length)
long conn_inbuf_len(Connection *conn)
void fdset_unregister(FDSet *set, int fd)
int conn_eof(Connection *conn)
static void lock_out(Connection *conn)
volatile sig_atomic_t claimed
conn_callback_data_destroyer_t * callback_data_destroyer
#define octstr_get_cstr(ostr)
#define octstr_copy(ostr, from, len)
long octstr_search_char(const Octstr *ostr, int ch, long pos)
void fdset_register(FDSet *set, int fd, int events, fdset_callback_t callback, void *data)
static Octstr * unlocked_get(Connection *conn, long length)
#define DEFAULT_OUTPUT_BUFFERING
Connection * conn_open_tcp_nb_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
void conn_callback_data_destroyer_t(void *data)
static Octstr * ssl_client_certkey_file
void conn_claim(Connection *conn)
void conn_set_output_buffering(Connection *conn, unsigned int size)
Octstr * octstr_imm(const char *cstr)
int conn_write(Connection *conn, Octstr *data)
int conn_get_connect_result(Connection *conn)
Octstr * conn_read_packet(Connection *conn, int startmark, int endmark)
int conn_get_id(Connection *conn)
void conn_config_ssl(CfgGroup *grp)
void octstr_delete(Octstr *ostr1, long pos, long len)
static void unlocked_read(Connection *conn)
void conn_destroy(Connection *conn)
int conn_register_real(Connection *conn, FDSet *fdset, conn_callback_t callback, void *data, conn_callback_data_destroyer_t *data_destroyer)
Connection * conn_open_tcp_with_port(Octstr *host, int port, int our_port, Octstr *our_host)
unsigned long(* CRYPTO_CALLBACK_PTR)(void)
void warning(int err, const char *fmt,...)
long conn_outbuf_len(Connection *conn)
int tcpip_connect_to_server_with_port(char *hostname, int port, int our_port, const char *source_addr)
void octstr_destroy(Octstr *ostr)
void conn_callback_t(Connection *conn, void *data)
#define octstr_create(cstr)
void mutex_destroy(Mutex *mutex)
Octstr * conn_read_withlen(Connection *conn)
int conn_write_withlen(Connection *conn, Octstr *data)
long octstr_write_data(Octstr *ostr, int fd, long from)
int gwthread_pollfd(int fd, int events, double timeout)
static void poll_callback(int fd, int revents, void *data)
static void unlock_in_real(Connection *conn, char *file, int line, const char *func)
int tcpip_connect_nb_to_server_with_port(char *hostname, int port, int our_port, const char *source_addr, int *done)
long octstr_len(const Octstr *ostr)
void conn_unregister(Connection *conn)
long decode_network_long(unsigned char *data)
enum Connection::@56 connected
static long unlocked_inbuf_len(Connection *conn)
int conn_wait(Connection *conn, double seconds)
static void unlock_out_real(Connection *conn, char *file, int line, const char *func)
static void lock_in(Connection *conn)
static long unlocked_write(Connection *conn)
Octstr * conn_read_fixed(Connection *conn, long length)
int conn_error(Connection *conn)
void octstr_get_many_chars(char *buf, Octstr *ostr, long pos, long len)
int octstr_get_char(const Octstr *ostr, long pos)
Octstr * conn_read_everything(Connection *conn)
Connection * conn_wrap_fd(int fd, int ssl)
int conn_flush(Connection *conn)