diff options
Diffstat (limited to 'vio/viossl.c')
-rw-r--r-- | vio/viossl.c | 160 |
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 */ |