int mowgli_vio_openssl_default_listen(mowgli_vio_t *vio, int backlog) { return_val_if_fail(vio, -255); mowgli_ssl_connection_t *connection = vio->privdata; const SSL_METHOD *method; const int fd = mowgli_vio_getfd(vio); vio->error.op = MOWGLI_VIO_ERR_OP_LISTEN; switch (connection->settings.ssl_version) { case MOWGLI_VIO_SSLFLAGS_SSLV2: method = SSLv23_server_method(); break; case MOWGLI_VIO_SSLFLAGS_SSLV3: method = SSLv3_server_method(); break; case MOWGLI_VIO_SSLFLAGS_TLSV10: case MOWGLI_VIO_SSLFLAGS_TLSV11: case MOWGLI_VIO_SSLFLAGS_TLSV12: method = TLSv1_server_method(); break; default: /* Compat method */ method = SSLv23_server_method(); } connection->ssl_context = SSL_CTX_new((SSL_METHOD *) method); if (connection->ssl_context == NULL) return mowgli_vio_err_sslerrcode(vio, ERR_get_error()); connection->ssl_handle = SSL_new(connection->ssl_context); if (connection->ssl_handle == NULL) return mowgli_vio_err_sslerrcode(vio, ERR_get_error()); SSL_set_accept_state(connection->ssl_handle); SSL_CTX_set_options(connection->ssl_context, SSL_OP_SINGLE_DH_USE); if (connection->settings.password_func) { SSL_CTX_set_default_passwd_cb(connection->ssl_context, connection->settings.password_func); SSL_CTX_set_default_passwd_cb_userdata(connection->ssl_context, vio->userdata); } if (SSL_CTX_use_certificate_file(connection->ssl_context, connection->settings.cert_path, SSL_FILETYPE_PEM) != 1) return mowgli_vio_err_sslerrcode(vio, ERR_get_error()); if (SSL_CTX_use_PrivateKey_file(connection->ssl_context, connection->settings.privatekey_path, SSL_FILETYPE_PEM) != 1) return mowgli_vio_err_sslerrcode(vio, ERR_get_error()); if (listen(fd, backlog) != 0) return mowgli_vio_err_errcode(vio, strerror, errno); if (!SSL_set_fd(connection->ssl_handle, fd)) return mowgli_vio_err_sslerrcode(vio, ERR_get_error()); mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISSERVER, true); vio->error.op = MOWGLI_VIO_ERR_OP_NONE; return 0; }
int mowgli_vio_openssl_default_accept(mowgli_vio_t *vio, mowgli_vio_t *newvio) { const int fd = mowgli_vio_getfd(vio); int afd; int ret; return_val_if_fail(fd != -1, -255); mowgli_ssl_connection_t *connection = vio->privdata; mowgli_ssl_connection_t *newconnection; vio->error.op = MOWGLI_VIO_ERR_OP_ACCEPT; if (!newvio) { const char errstr[] = "accept not called with valid new VIO object"; vio->error.type = MOWGLI_VIO_ERR_API; mowgli_strlcpy(vio->error.string, errstr, sizeof(errstr)); return mowgli_vio_error(vio); } if ((afd = accept(fd, (struct sockaddr *) &newvio->addr.addr, &(newvio->addr.addrlen))) < 0) { if (!mowgli_eventloop_ignore_errno(errno)) return mowgli_vio_err_errcode(vio, strerror, errno); else return 0; } newvio->io.fd = afd; mowgli_vio_openssl_setssl(newvio, &connection->settings, vio->ops); newconnection = newvio->privdata; newconnection->ssl_context = connection->ssl_context; newconnection->ssl_handle = SSL_new(newconnection->ssl_context); if (!SSL_set_fd(newconnection->ssl_handle, afd)) return mowgli_vio_err_sslerrcode(newvio, ERR_get_error()); if ((ret = SSL_accept(newconnection->ssl_handle)) != 1) { unsigned long err; switch (SSL_get_error(newconnection->ssl_handle, ret)) { case SSL_ERROR_WANT_READ: mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDREAD, true); MOWGLI_VIO_SETREAD(vio) return 0; case SSL_ERROR_WANT_WRITE: mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_NEEDWRITE, true); MOWGLI_VIO_SETWRITE(vio) return 0; case SSL_ERROR_ZERO_RETURN: return 0; case SSL_ERROR_SYSCALL: return mowgli_vio_err_errcode(newvio, strerror, errno); default: err = ERR_get_error(); break; } if (err > 0) { errno = EIO; return mowgli_vio_err_errcode(vio, strerror, errno); } return -1; }
int mowgli_vio_openssl_default_listen(mowgli_vio_t *vio, int backlog) { return_val_if_fail(vio, -255); mowgli_ssl_connection_t *connection = vio->privdata; const int fd = mowgli_vio_getfd(vio); vio->error.op = MOWGLI_VIO_ERR_OP_LISTEN; #ifndef MOWGLI_HAVE_OPENSSL_TLS_METHOD_API connection->ssl_context = SSL_CTX_new(SSLv23_server_method()); #else connection->ssl_context = SSL_CTX_new(TLS_server_method()); #endif if (connection->ssl_context == NULL) return mowgli_vio_err_sslerrcode(vio, ERR_get_error()); #ifndef MOWGLI_HAVE_OPENSSL_TLS_METHOD_API # ifdef SSL_OP_NO_SSLv2 SSL_CTX_set_options(connection->ssl_context, SSL_OP_NO_SSLv2); # endif # ifdef SSL_OP_NO_SSLv3 SSL_CTX_set_options(connection->ssl_context, SSL_OP_NO_SSLv3); # endif #endif connection->ssl_handle = SSL_new(connection->ssl_context); if (connection->ssl_handle == NULL) return mowgli_vio_err_sslerrcode(vio, ERR_get_error()); SSL_set_accept_state(connection->ssl_handle); SSL_CTX_set_options(connection->ssl_context, SSL_OP_SINGLE_DH_USE); #ifdef OPENSSL_EC_AVAILABLE # ifdef MOWGLI_HAVE_OPENSSL_ECDH_AUTO SSL_CTX_set_ecdh_auto(connection->ssl_context, 1); # else EC_KEY *ec_key_p256 = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (ec_key_p256 != NULL) { SSL_CTX_set_tmp_ecdh(connection->ssl_context, ec_key_p256); EC_KEY_free(ec_key_p256); ec_key_p256 = NULL; } # endif # ifdef SSL_OP_SINGLE_ECDH_USE SSL_CTX_set_options(connection->ssl_context, SSL_OP_SINGLE_ECDH_USE); # endif #endif if (connection->settings.password_func) { SSL_CTX_set_default_passwd_cb(connection->ssl_context, connection->settings.password_func); SSL_CTX_set_default_passwd_cb_userdata(connection->ssl_context, vio->userdata); } if (SSL_CTX_use_certificate_file(connection->ssl_context, connection->settings.cert_path, SSL_FILETYPE_PEM) != 1) return mowgli_vio_err_sslerrcode(vio, ERR_get_error()); if (SSL_CTX_use_PrivateKey_file(connection->ssl_context, connection->settings.privatekey_path, SSL_FILETYPE_PEM) != 1) return mowgli_vio_err_sslerrcode(vio, ERR_get_error()); if (listen(fd, backlog) != 0) return mowgli_vio_err_errcode(vio, strerror, errno); if (!SSL_set_fd(connection->ssl_handle, fd)) return mowgli_vio_err_sslerrcode(vio, ERR_get_error()); mowgli_vio_setflag(vio, MOWGLI_VIO_FLAGS_ISSERVER, true); vio->error.op = MOWGLI_VIO_ERR_OP_NONE; return 0; }