extern struct data_ops ssl_sock;
int ssl_sock_handshake(struct connection *conn, unsigned int flag);
+void ssl_sock_infocbk(const SSL *ssl, int where, int ret);
#endif /* _PROTO_SSL_SOCK_H */
SSL_CTX_set_mode(listener->ssl_ctx.ctx, sslmode);
SSL_CTX_set_verify(listener->ssl_ctx.ctx, SSL_VERIFY_NONE, NULL);
SSL_CTX_set_session_cache_mode(listener->ssl_ctx.ctx, SSL_SESS_CACHE_SERVER);
+ SSL_CTX_set_info_callback(listener->ssl_ctx.ctx, ssl_sock_infocbk);
if (SSL_CTX_use_PrivateKey_file(listener->ssl_ctx.ctx, listener->ssl_cert, SSL_FILETYPE_PEM) <= 0) {
Alert("Proxy '%s': unable to load SSL private key from file '%s' in listener %d (%s:%d).\n",
#include <types/global.h>
+
+void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
+{
+ struct connection *conn = (struct connection *)SSL_get_app_data(ssl);
+ (void)ret; /* shut gcc stupid warning */
+
+ if (where & SSL_CB_HANDSHAKE_START) {
+ /* Disable renegotiation (CVE-2009-3555) */
+ if (conn->flags & CO_FL_CONNECTED)
+ conn->flags |= CO_FL_ERROR;
+ }
+}
+
/*
* This function is called if SSL * context is not yet allocated. The function
* is designed to be called before any other data-layer operation and sets the
/* set fd on SSL session context */
SSL_set_fd(conn->data_ctx, conn->t.sock.fd);
+ /* set connection pointer */
+ SSL_set_app_data(conn->data_ctx, conn);
+
/* leave init state and start handshake */
conn->flags |= CO_FL_SSL_WAIT_HS;
return 0;
*/
while (try) {
ret = SSL_read(conn->data_ctx, bi_end(buf), try);
-
+ if (conn->flags & CO_FL_ERROR) {
+ /* CO_FL_ERROR may be set by ssl_sock_infocbk */
+ break;
+ }
if (ret > 0) {
buf->i += ret;
done += ret;
try = buf->data + try - buf->p;
ret = SSL_write(conn->data_ctx, bo_ptr(buf), try);
+ if (conn->flags & CO_FL_ERROR) {
+ /* CO_FL_ERROR may be set by ssl_sock_infocbk */
+ break;
+ }
if (ret > 0) {
buf->o -= ret;
done += ret;