summaryrefslogtreecommitdiff
path: root/vio/viossl.c
diff options
context:
space:
mode:
Diffstat (limited to 'vio/viossl.c')
-rw-r--r--vio/viossl.c160
1 files changed, 33 insertions, 127 deletions
diff --git a/vio/viossl.c b/vio/viossl.c
index c6f70081d18..19fd6e0f0ab 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -34,31 +34,6 @@
#include <my_sys.h>
#include <my_net.h>
#include <m_string.h>
-#ifdef HAVE_POLL
-#include <sys/poll.h>
-#endif
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-
-#if defined(__EMX__)
-#define ioctlsocket ioctl
-#endif /* defined(__EMX__) */
-
-#if defined(MSDOS) || defined(__WIN__)
-#ifdef __WIN__
-#undef errno
-#undef EINTR
-#undef EAGAIN
-#define errno WSAGetLastError()
-#define EINTR WSAEINTR
-#define EAGAIN WSAEINPROGRESS
-#endif /* __WIN__ */
-#define O_NONBLOCK 1 /* For emulation of fcntl() */
-#endif
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK EAGAIN
-#endif
#ifndef __WIN__
#define HANDLE void *
@@ -83,7 +58,7 @@ report_errors()
if (!any_ssl_error) {
DBUG_PRINT("info", ("No OpenSSL errors."));
}
- DBUG_PRINT("info", ("BTW, errno=%d", errno));
+ DBUG_PRINT("info", ("BTW, errno=%d", socket_errno));
DBUG_VOID_RETURN;
}
@@ -102,7 +77,7 @@ void vio_ssl_delete(Vio * vio)
int vio_ssl_errno(Vio *vio __attribute__((unused)))
{
- return errno; /* On Win32 this mapped to WSAGetLastError() */
+ return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
}
@@ -118,8 +93,11 @@ int vio_ssl_read(Vio * vio, gptr buf, int size)
#endif /* DBUG_OFF */
r = SSL_read(vio->ssl_, buf, size);
#ifndef DBUG_OFF
- if ( r< 0)
+ if ( r<= 0) {
+ r=SSL_get_error(vio->ssl_, r);
+ DBUG_PRINT("info",("SSL_get_error returned %d",r));
report_errors();
+ }
#endif /* DBUG_OFF */
DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(r);
@@ -192,8 +170,9 @@ int vio_ssl_keepalive(Vio* vio, my_bool set_keep_alive)
my_bool
vio_ssl_should_retry(Vio * vio __attribute__((unused)))
{
- int en = errno;
- return en == EAGAIN || en == EINTR || en == EWOULDBLOCK;
+ int en = socket_errno;
+ return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
+ en == SOCKET_EWOULDBLOCK);
}
@@ -207,7 +186,6 @@ int vio_ssl_close(Vio * vio)
r = SSL_shutdown(vio->ssl_);
SSL_free(vio->ssl_);
vio->ssl_= 0;
- vio->bio_ = 0;
}
if (shutdown(vio->sd,2))
r= -1;
@@ -215,7 +193,7 @@ int vio_ssl_close(Vio * vio)
r= -1;
if (r)
{
- DBUG_PRINT("error", ("close() failed, error: %d",errno));
+ DBUG_PRINT("error", ("close() failed, error: %d",socket_errno));
report_errors();
/* FIXME: error handling (not critical for MySQL) */
}
@@ -255,7 +233,7 @@ my_bool vio_ssl_peer_addr(Vio * vio, char *buf)
if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
&addrLen) != 0)
{
- DBUG_PRINT("exit", ("getpeername, error: %d", errno));
+ DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
DBUG_RETURN(1);
}
/* FIXME */
@@ -298,12 +276,11 @@ my_bool vio_ssl_poll_read(Vio *vio,uint timeout)
#endif
}
-void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio)
+void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout)
{
- X509* client_cert;
+ X509* client_cert;
char *str;
- int i;
-// const int blocking = vio_is_blocking(vio);
+ char buf[1024];
DBUG_ENTER("sslaccept");
DBUG_PRINT("enter", ("sd=%d ptr=%p", vio->sd,ptr));
vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
@@ -316,49 +293,12 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio)
DBUG_VOID_RETURN;
}
DBUG_PRINT("info", ("ssl_=%p",vio->ssl_));
+ SSL_clear(vio->ssl_);
vio_blocking(vio, FALSE);
+ SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout);
SSL_set_fd(vio->ssl_,vio->sd);
SSL_set_accept_state(vio->ssl_);
-
- /* FIXME possibly infinite loop */
- while (SSL_is_init_finished(vio->ssl_)) {
- DBUG_PRINT("info",("SSL_is_init_finished(vio->ssl_) is not 1"));
- if((i=SSL_do_handshake(vio->ssl_))!=SSL_ERROR_NONE)
- {
- DBUG_PRINT("info",("*** errno %d",errno));
- switch (SSL_get_error(vio->ssl_,i))
- {
- case SSL_ERROR_NONE:
- DBUG_PRINT("info",("SSL_ERROR_NONE: handshake finished"));
- break;
- case SSL_ERROR_SSL:
- DBUG_PRINT("info",("SSL_ERROR_SSL: SSL protocol error "));
- break;
- case SSL_ERROR_WANT_CONNECT:
- DBUG_PRINT("info",("SSL_ERROR_WANT_CONNECT:If you are doing non-blocking connects call again when the connection is established"));
- break;
- case SSL_ERROR_WANT_READ:
- DBUG_PRINT("info",("SSL_ERROR_WANT_READ: if non-blocking etc, call again when data is available"));
- break;
- case SSL_ERROR_WANT_WRITE:
- DBUG_PRINT("info",("SSL_ERROR_WANT_WRITE: if non-blocking etc, call again when data is available to write"));
- break;
- case SSL_ERROR_WANT_X509_LOOKUP:
- DBUG_PRINT("info",("SSL_ERROR_WANT_X509_LOOKUP: /* not used yet but could be :-) */"));
- break;
- case SSL_ERROR_SYSCALL:
- DBUG_PRINT("info",("SSL_ERROR_SYSCALL: An error than the error code can be found in errno (%d)",errno));
- break;
- case SSL_ERROR_ZERO_RETURN:
- DBUG_PRINT("info",("SSL_ERROR_ZERO_RETURN: 0 returned on the read, normally means the socket is closed :-) */"));
- break;
- default:
- DBUG_PRINT("info",("Unknown SSL error returned"));
- break;
- }
- }
- usleep(100);
- }
+ SSL_do_handshake(vio->ssl_);
vio->open_ = TRUE;
#ifndef DBUF_OFF
DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
@@ -374,23 +314,28 @@ void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio)
DBUG_PRINT("info",("\t issuer: %s", str));
free (str);
- /* We could do all sorts of certificate verification stuff here before
- * deallocating the certificate. */
-
X509_free (client_cert);
} else
DBUG_PRINT("info",("Client does not have certificate."));
+
+ str=SSL_get_shared_ciphers(vio->ssl_, buf, sizeof(buf));
+ if(str)
+ {
+ DBUG_PRINT("info",("SSL_get_shared_ciphers() returned '%s'",str));
+ }
+ else
+ {
+ DBUG_PRINT("info",("no shared ciphers!"));
+ }
+
#endif
DBUG_VOID_RETURN;
}
-void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio)
+void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout)
{
char *str;
-// char s[]="abc";
-int i;
X509* server_cert;
- const int blocking = vio_is_blocking(vio);
DBUG_ENTER("sslconnect");
DBUG_PRINT("enter", ("sd=%d ptr=%p ctx: %p", vio->sd,ptr,ptr->ssl_context_));
vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
@@ -403,50 +348,13 @@ int i;
report_errors();
DBUG_VOID_RETURN;
}
- DBUG_PRINT("info", ("ssl_=%p",vio->ssl_));
+ DBUG_PRINT("info",("ssl_=%p",vio->ssl_));
+ SSL_clear(vio->ssl_);
vio_blocking(vio, FALSE);
+ SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout);
SSL_set_fd (vio->ssl_, vio->sd);
SSL_set_connect_state(vio->ssl_);
-
- /* FIXME possibly infinite loop */
- while (SSL_is_init_finished(vio->ssl_)) {
- DBUG_PRINT("info",("SSL_is_init_finished(vio->ssl_) is not 1"));
- if((i=SSL_do_handshake(vio->ssl_))!=SSL_ERROR_NONE)
- {
- DBUG_PRINT("info",("*** errno %d",errno));
- switch (SSL_get_error(vio->ssl_,i))
- {
- case SSL_ERROR_NONE:
- DBUG_PRINT("info",("SSL_ERROR_NONE: handshake finished"));
- break;
- case SSL_ERROR_SSL:
- DBUG_PRINT("info",("SSL_ERROR_SSL: SSL protocol error "));
- break;
- case SSL_ERROR_WANT_CONNECT:
- DBUG_PRINT("info",("SSL_ERROR_WANT_CONNECT:If you are doing non-blocking connects call again when the connection is established"));
- break;
- case SSL_ERROR_WANT_READ:
- DBUG_PRINT("info",("SSL_ERROR_WANT_READ: if non-blocking etc, call again when data is available"));
- break;
- case SSL_ERROR_WANT_WRITE:
- DBUG_PRINT("info",("SSL_ERROR_WANT_WRITE: if non-blocking etc, call again when data is available to write"));
- break;
- case SSL_ERROR_WANT_X509_LOOKUP:
- DBUG_PRINT("info",("SSL_ERROR_WANT_X509_LOOKUP: /* not used yet but could be :-) */"));
- break;
- case SSL_ERROR_SYSCALL:
- DBUG_PRINT("info",("SSL_ERROR_SYSCALL: An error than the error code can be found in errno (%d)",errno));
- break;
- case SSL_ERROR_ZERO_RETURN:
- DBUG_PRINT("info",("SSL_ERROR_ZERO_RETURN: 0 returned on the read, normally means the socket is closed :-) */"));
- break;
- default:
- DBUG_PRINT("info",("Unknown SSL error returned"));
- break;
- }
- }
- usleep(100);
- }
+ SSL_do_handshake(vio->ssl_);
vio->open_ = TRUE;
#ifndef DBUG_OFF
DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
@@ -469,9 +377,7 @@ int i;
} else
DBUG_PRINT("info",("Server does not have certificate."));
#endif
- vio_blocking(vio, blocking);
DBUG_VOID_RETURN;
}
-
#endif /* HAVE_OPENSSL */