summaryrefslogtreecommitdiff
path: root/vio
diff options
context:
space:
mode:
authorunknown <msvensson@neptunus.(none)>2006-05-12 11:19:37 +0200
committerunknown <msvensson@neptunus.(none)>2006-05-12 11:19:37 +0200
commite1827da7fbfebe19dd7e3265222e9369fe8fb532 (patch)
tree4063ebe15cf97d49ecbc21d4d7ae249bd5f62e19 /vio
parente8a5d25bea8f4723ab0c357a071467e5f1915db5 (diff)
parent144c7622c7906ac554b5bbaa60c4e89113dac1e5 (diff)
downloadmariadb-git-e1827da7fbfebe19dd7e3265222e9369fe8fb532.tar.gz
Merge neptunus.(none):/home/msvensson/mysql/mysql-5.1-md
into neptunus.(none):/home/msvensson/mysql/mysql-5.1
Diffstat (limited to 'vio')
-rw-r--r--vio/test-ssl.c4
-rw-r--r--vio/test-sslclient.c2
-rw-r--r--vio/test-sslserver.c4
-rw-r--r--vio/vio.c29
-rw-r--r--vio/vio_priv.h22
-rw-r--r--vio/viossl.c402
-rw-r--r--vio/viosslfactories.c311
7 files changed, 291 insertions, 483 deletions
diff --git a/vio/test-ssl.c b/vio/test-ssl.c
index a94eb1a21ff..f8172426e38 100644
--- a/vio/test-ssl.c
+++ b/vio/test-ssl.c
@@ -57,8 +57,8 @@ main(int argc, char** argv)
char* cipher=0;
int child_pid,sv[2];
my_bool unused;
- struct st_VioSSLAcceptorFd* ssl_acceptor=0;
- struct st_VioSSLConnectorFd* ssl_connector=0;
+ struct st_VioSSLFd* ssl_acceptor= 0;
+ struct st_VioSSLFd* ssl_connector= 0;
Vio* client_vio=0, *server_vio=0;
MY_INIT(argv[0]);
DBUG_PROCESS(argv[0]);
diff --git a/vio/test-sslclient.c b/vio/test-sslclient.c
index 3811ba0fb6a..49d6768c884 100644
--- a/vio/test-sslclient.c
+++ b/vio/test-sslclient.c
@@ -46,7 +46,7 @@ main( int argc __attribute__((unused)),
{
char client_key[] = "../SSL/client-key.pem", client_cert[] = "../SSL/client-cert.pem";
char ca_file[] = "../SSL/cacert.pem", *ca_path = 0, *cipher=0;
- struct st_VioSSLConnectorFd* ssl_connector=0;
+ struct st_VioSSLFd* ssl_connector= 0;
struct sockaddr_in sa;
Vio* client_vio=0;
int err;
diff --git a/vio/test-sslserver.c b/vio/test-sslserver.c
index e4d32a75264..daec3a6e6f9 100644
--- a/vio/test-sslserver.c
+++ b/vio/test-sslserver.c
@@ -44,7 +44,7 @@ fatal_error( const char* r)
typedef struct {
int sd;
- struct st_VioSSLAcceptorFd* ssl_acceptor;
+ struct st_VioSSLFd* ssl_acceptor;
} TH_ARGS;
static void
@@ -82,7 +82,7 @@ main(int argc __attribute__((unused)), char** argv)
char ca_file[] = "../SSL/cacert.pem",
*ca_path = 0,
*cipher = 0;
- struct st_VioSSLAcceptorFd* ssl_acceptor;
+ struct st_VioSSLFd* ssl_acceptor;
pthread_t th;
TH_ARGS th_args;
diff --git a/vio/vio.c b/vio/vio.c
index 9ace22e3780..f20acb249ef 100644
--- a/vio/vio.c
+++ b/vio/vio.c
@@ -88,19 +88,19 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
if (type == VIO_TYPE_SSL)
{
vio->viodelete =vio_delete;
- vio->vioerrno =vio_ssl_errno;
+ vio->vioerrno =vio_errno;
vio->read =vio_ssl_read;
vio->write =vio_ssl_write;
- vio->fastsend =vio_ssl_fastsend;
- vio->viokeepalive =vio_ssl_keepalive;
- vio->should_retry =vio_ssl_should_retry;
- vio->was_interrupted=vio_ssl_was_interrupted;
+ vio->fastsend =vio_fastsend;
+ vio->viokeepalive =vio_keepalive;
+ vio->should_retry =vio_should_retry;
+ vio->was_interrupted=vio_was_interrupted;
vio->vioclose =vio_ssl_close;
- vio->peer_addr =vio_ssl_peer_addr;
- vio->in_addr =vio_ssl_in_addr;
+ vio->peer_addr =vio_peer_addr;
+ vio->in_addr =vio_in_addr;
vio->vioblocking =vio_ssl_blocking;
vio->is_blocking =vio_is_blocking;
- vio->timeout =vio_ssl_timeout;
+ vio->timeout =vio_timeout;
}
else /* default is VIO_TYPE_TCPIP */
#endif /* HAVE_OPENSSL */
@@ -233,3 +233,16 @@ void vio_delete(Vio* vio)
my_free((gptr) vio,MYF(0));
}
}
+
+
+/*
+ Cleanup memory allocated by vio or the
+ components below it when application finish
+
+*/
+void vio_end(void)
+{
+#ifdef HAVE_YASSL
+ yaSSL_CleanUp();
+#endif
+}
diff --git a/vio/vio_priv.h b/vio/vio_priv.h
index eb495025ddd..db331abdea8 100644
--- a/vio/vio_priv.h
+++ b/vio/vio_priv.h
@@ -30,28 +30,10 @@ void vio_ignore_timeout(Vio *vio, uint which, uint timeout);
int vio_ssl_read(Vio *vio,gptr buf, int size);
int vio_ssl_write(Vio *vio,const gptr buf,int size);
-void vio_ssl_timeout(Vio *vio, uint which, uint timeout);
-
-/* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. */
-int vio_ssl_fastsend(Vio *vio);
-/* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible. */
-int vio_ssl_keepalive(Vio *vio, my_bool onoff);
-/* Whenever we should retry the last read/write operation. */
-my_bool vio_ssl_should_retry(Vio *vio);
-/* Check that operation was timed out */
-my_bool vio_ssl_was_interrupted(Vio *vio);
+
/* When the workday is over... */
int vio_ssl_close(Vio *vio);
-/* Return last error number */
-int vio_ssl_errno(Vio *vio);
-my_bool vio_ssl_peer_addr(Vio *vio, char *buf, uint16 *port);
-void vio_ssl_in_addr(Vio *vio, struct in_addr *in);
+
int vio_ssl_blocking(Vio *vio, my_bool set_blocking_mode, my_bool *old_mode);
-/* Single copy for server */
-enum vio_ssl_acceptorfd_state
-{
- state_connect = 1,
- state_accept = 2
-};
#endif /* HAVE_OPENSSL */
diff --git a/vio/viossl.c b/vio/viossl.c
index a0262a79209..e869493c604 100644
--- a/vio/viossl.c
+++ b/vio/viossl.c
@@ -51,384 +51,240 @@ static int SSL_set_fd_bsd(SSL *s, int fd)
static void
-report_errors()
+report_errors(SSL* ssl)
{
unsigned long l;
- const char* file;
- const char* data;
- int line,flags;
+ const char *file;
+ const char *data;
+ int line, flags;
+#ifndef DBUG_OFF
+ char buf[512];
+#endif
+
DBUG_ENTER("report_errors");
- while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)))
+ while ((l= ERR_get_error_line_data(&file,&line,&data,&flags)))
{
- char buf[512];
DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
file,line,(flags&ERR_TXT_STRING)?data:"")) ;
}
- DBUG_PRINT("info", ("errno: %d", socket_errno));
- DBUG_VOID_RETURN;
-}
+ if (ssl)
+ DBUG_PRINT("error", ("error: %s",
+ ERR_error_string(SSL_get_error(ssl, l), buf)));
-int vio_ssl_errno(Vio *vio __attribute__((unused)))
-{
- return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
+ DBUG_PRINT("info", ("socket_errno: %d", socket_errno));
+ DBUG_VOID_RETURN;
}
-int vio_ssl_read(Vio * vio, gptr buf, int size)
+int vio_ssl_read(Vio *vio, gptr buf, int size)
{
int r;
DBUG_ENTER("vio_ssl_read");
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d, ssl_: 0x%p",
vio->sd, buf, size, vio->ssl_arg));
- if ((r= SSL_read((SSL*) vio->ssl_arg, buf, size)) < 0)
- {
- int err= SSL_get_error((SSL*) vio->ssl_arg, r);
- DBUG_PRINT("error",("SSL_read(): %d SSL_get_error(): %d", r, err));
- report_errors();
- }
+ r= SSL_read((SSL*) vio->ssl_arg, buf, size);
+#ifndef DBUG_OFF
+ if (r < 0)
+ report_errors((SSL*) vio->ssl_arg);
+#endif
DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(r);
}
-int vio_ssl_write(Vio * vio, const gptr buf, int size)
+int vio_ssl_write(Vio *vio, const gptr buf, int size)
{
int r;
DBUG_ENTER("vio_ssl_write");
DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size));
- if ((r= SSL_write((SSL*) vio->ssl_arg, buf, size)) < 0)
- report_errors();
- DBUG_PRINT("exit", ("%d", r));
- DBUG_RETURN(r);
-}
-
-
-int vio_ssl_fastsend(Vio * vio __attribute__((unused)))
-{
- int r=0;
- DBUG_ENTER("vio_ssl_fastsend");
-
-#if defined(IPTOS_THROUGHPUT)
- {
- int tos= IPTOS_THROUGHPUT;
- r= setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos));
- }
-#endif /* IPTOS_THROUGHPUT */
- if (!r)
- {
-#ifdef __WIN__
- BOOL nodelay= 1;
- r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (const char*) &nodelay,
- sizeof(nodelay));
-#else
- int nodelay= 1;
- r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay,
- sizeof(nodelay));
-#endif /* __WIN__ */
- }
- if (r)
- {
- DBUG_PRINT("warning", ("Couldn't set socket option for fast send"));
- r= -1;
- }
+ r= SSL_write((SSL*) vio->ssl_arg, buf, size);
+#ifndef DBUG_OFF
+ if (r < 0)
+ report_errors((SSL*) vio->ssl_arg);
+#endif
DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(r);
}
-int vio_ssl_keepalive(Vio* vio, my_bool set_keep_alive)
+int vio_ssl_close(Vio *vio)
{
- int r=0;
- DBUG_ENTER("vio_ssl_keepalive");
- DBUG_PRINT("enter", ("sd: %d, set_keep_alive: %d", vio->sd, (int)
- set_keep_alive));
- if (vio->type != VIO_TYPE_NAMEDPIPE)
- {
- uint opt = (set_keep_alive) ? 1 : 0;
- r= setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
- sizeof(opt));
- }
- DBUG_RETURN(r);
-}
-
-
-my_bool
-vio_ssl_should_retry(Vio * vio __attribute__((unused)))
-{
- int en = socket_errno;
- return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
- en == SOCKET_EWOULDBLOCK);
-}
-
-
-my_bool
-vio_ssl_was_interrupted(Vio *vio __attribute__((unused)))
-{
- int en= socket_errno;
- return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
- en == SOCKET_EWOULDBLOCK || en == SOCKET_ETIMEDOUT);
-}
-
-
-int vio_ssl_close(Vio * vio)
-{
- int r;
+ int r= 0;
+ SSL *ssl= (SSL*)vio->ssl_arg;
DBUG_ENTER("vio_ssl_close");
- r=0;
- if ((SSL*) vio->ssl_arg)
- {
- r = SSL_shutdown((SSL*) vio->ssl_arg);
- SSL_free((SSL*) vio->ssl_arg);
- vio->ssl_arg= 0;
- }
- if (vio->sd >= 0)
- {
- if (shutdown(vio->sd, 2))
- r= -1;
- if (closesocket(vio->sd))
- r= -1;
- }
- if (r)
- {
- DBUG_PRINT("error", ("close() failed, error: %d",socket_errno));
- report_errors();
- /* FIXME: error handling (not critical for MySQL) */
- }
- vio->type= VIO_CLOSED;
- vio->sd= -1;
- DBUG_RETURN(r);
-}
-
-const char *vio_ssl_description(Vio * vio)
-{
- return vio->desc;
-}
-
-enum enum_vio_type vio_ssl_type(Vio* vio)
-{
- return vio->type;
-}
-
-my_socket vio_ssl_fd(Vio* vio)
-{
- return vio->sd;
-}
-
-
-my_bool vio_ssl_peer_addr(Vio * vio, char *buf, uint16 *port)
-{
- DBUG_ENTER("vio_ssl_peer_addr");
- DBUG_PRINT("enter", ("sd: %d", vio->sd));
- if (vio->localhost)
- {
- strmov(buf,"127.0.0.1");
- *port=0;
- }
- else
+ if (ssl)
{
- size_socket addrLen = sizeof(struct sockaddr);
- if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
- &addrLen) != 0)
+ switch ((r= SSL_shutdown(ssl)))
{
- DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
- DBUG_RETURN(1);
+ case 1: /* Shutdown successful */
+ break;
+ case 0: /* Shutdown not yet finished, call it again */
+ if ((r= SSL_shutdown(ssl) >= 0))
+ break;
+ /* Fallthrough */
+ default: /* Shutdown failed */
+ DBUG_PRINT("vio_error", ("SSL_shutdown() failed, error: %s",
+ SSL_get_error(ssl, r)));
+ break;
}
-#ifdef TO_BE_FIXED
- my_inet_ntoa(vio->remote.sin_addr,buf);
- *port= 0;
-#else
- strmov(buf, "unknown");
- *port= 0;
-#endif
+ SSL_free(ssl);
+ vio->ssl_arg= 0;
}
- DBUG_PRINT("exit", ("addr: %s", buf));
- DBUG_RETURN(0);
+ DBUG_RETURN(vio_close(vio));
}
-void vio_ssl_in_addr(Vio *vio, struct in_addr *in)
+int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
{
- DBUG_ENTER("vio_ssl_in_addr");
- if (vio->localhost)
- bzero((char*) in, sizeof(*in));
- else
- *in=vio->remote.sin_addr;
- DBUG_VOID_RETURN;
-}
-
-
-/*
- TODO: Add documentation
-*/
-
-int sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout)
-{
- char *str;
- char buf[1024];
- X509* client_cert;
+ SSL *ssl;
my_bool unused;
my_bool net_blocking;
enum enum_vio_type old_type;
DBUG_ENTER("sslaccept");
- DBUG_PRINT("enter", ("sd: %d ptr: Ox%p, timeout: %d",
+ DBUG_PRINT("enter", ("sd: %d ptr: %p, timeout: %d",
vio->sd, ptr, timeout));
old_type= vio->type;
- net_blocking = vio_is_blocking(vio);
+ net_blocking= vio_is_blocking(vio);
vio_blocking(vio, 1, &unused); /* Must be called before reset */
- vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
- vio->ssl_arg= 0;
- if (!(vio->ssl_arg= (void*) SSL_new(ptr->ssl_context)))
+ vio_reset(vio, VIO_TYPE_SSL, vio->sd, 0, FALSE);
+
+ if (!(ssl= SSL_new(ptr->ssl_context)))
{
DBUG_PRINT("error", ("SSL_new failure"));
- report_errors();
+ report_errors(ssl);
vio_reset(vio, old_type,vio->sd,0,FALSE);
vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1);
}
- DBUG_PRINT("info", ("ssl_: Ox%p timeout: %ld",
- (SSL*) vio->ssl_arg, timeout));
- SSL_clear((SSL*) vio->ssl_arg);
- SSL_SESSION_set_timeout(SSL_get_session((SSL*) vio->ssl_arg), timeout);
- SSL_set_fd((SSL*) vio->ssl_arg,vio->sd);
- SSL_set_accept_state((SSL*) vio->ssl_arg);
- if (SSL_do_handshake((SSL*) vio->ssl_arg) < 1)
+ vio->ssl_arg= (void*)ssl;
+ DBUG_PRINT("info", ("ssl_: %p timeout: %ld", ssl, timeout));
+ SSL_clear(ssl);
+ SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
+ SSL_set_fd(ssl, vio->sd);
+ SSL_set_accept_state(ssl);
+ if (SSL_do_handshake(ssl) < 1)
{
DBUG_PRINT("error", ("SSL_do_handshake failure"));
- report_errors();
- SSL_free((SSL*) vio->ssl_arg);
+ report_errors(ssl);
+ SSL_free(ssl);
vio->ssl_arg= 0;
vio_reset(vio, old_type,vio->sd,0,FALSE);
vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1);
}
+
#ifndef DBUG_OFF
- DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
- ,SSL_get_cipher_name((SSL*) vio->ssl_arg)));
- client_cert = SSL_get_peer_certificate ((SSL*) vio->ssl_arg);
- if (client_cert != NULL)
{
- DBUG_PRINT("info",("Client certificate:"));
- str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
- DBUG_PRINT("info",("\t subject: %s", str));
- free (str);
+ char buf[1024];
+ X509 *client_cert;
+ DBUG_PRINT("info",("cipher_name= '%s'", SSL_get_cipher_name(ssl)));
- str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0);
- DBUG_PRINT("info",("\t issuer: %s", str));
- free (str);
+ if ((client_cert= SSL_get_peer_certificate (ssl)))
+ {
+ DBUG_PRINT("info",("Client certificate:"));
+ X509_NAME_oneline (X509_get_subject_name (client_cert),
+ buf, sizeof(buf));
+ DBUG_PRINT("info",("\t subject: %s", buf));
- X509_free (client_cert);
- }
- else
- DBUG_PRINT("info",("Client does not have certificate."));
+ X509_NAME_oneline (X509_get_issuer_name (client_cert),
+ buf, sizeof(buf));
+ DBUG_PRINT("info",("\t issuer: %s", buf));
- str=SSL_get_shared_ciphers((SSL*) vio->ssl_arg, buf, sizeof(buf));
- if (str)
- {
- DBUG_PRINT("info",("SSL_get_shared_ciphers() returned '%s'",str));
- }
- else
- {
- DBUG_PRINT("info",("no shared ciphers!"));
- }
+ X509_free (client_cert);
+ }
+ else
+ DBUG_PRINT("info",("Client does not have certificate."));
+ if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
+ {
+ DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
+ }
+ else
+ DBUG_PRINT("info",("no shared ciphers!"));
+ }
#endif
+
DBUG_RETURN(0);
}
-int sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout)
+int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
{
- char *str;
- X509* server_cert;
+ SSL *ssl;
my_bool unused;
my_bool net_blocking;
- enum enum_vio_type old_type;
+ enum enum_vio_type old_type;
+
DBUG_ENTER("sslconnect");
- DBUG_PRINT("enter", ("sd: %d ptr: 0x%p ctx: 0x%p",
- vio->sd,ptr,ptr->ssl_context));
+ DBUG_PRINT("enter", ("sd: %d, ptr: %p, ctx: %p",
+ vio->sd, ptr, ptr->ssl_context));
old_type= vio->type;
- net_blocking = vio_is_blocking(vio);
+ net_blocking= vio_is_blocking(vio);
vio_blocking(vio, 1, &unused); /* Must be called before reset */
- vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
- vio->ssl_arg= 0;
- if (!(vio->ssl_arg = SSL_new(ptr->ssl_context)))
+ vio_reset(vio, VIO_TYPE_SSL, vio->sd, 0, FALSE);
+ if (!(ssl= SSL_new(ptr->ssl_context)))
{
DBUG_PRINT("error", ("SSL_new failure"));
- report_errors();
- vio_reset(vio, old_type,vio->sd,0,FALSE);
- vio_blocking(vio, net_blocking, &unused);
+ report_errors(ssl);
+ vio_reset(vio, old_type, vio->sd, 0, FALSE);
+ vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1);
}
- DBUG_PRINT("info", ("ssl_: 0x%p timeout: %ld",
- (SSL*) vio->ssl_arg, timeout));
- SSL_clear((SSL*) vio->ssl_arg);
- SSL_SESSION_set_timeout(SSL_get_session((SSL*) vio->ssl_arg), timeout);
- SSL_set_fd ((SSL*) vio->ssl_arg, vio_ssl_fd(vio));
- SSL_set_connect_state((SSL*) vio->ssl_arg);
- if (SSL_do_handshake((SSL*) vio->ssl_arg) < 1)
+ vio->ssl_arg= (void*)ssl;
+ DBUG_PRINT("info", ("ssl: %p, timeout: %ld", ssl, timeout));
+ SSL_clear(ssl);
+ SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
+ SSL_set_fd(ssl, vio->sd);
+ SSL_set_connect_state(ssl);
+ if (SSL_do_handshake(ssl) < 1)
{
DBUG_PRINT("error", ("SSL_do_handshake failure"));
- report_errors();
- SSL_free((SSL*) vio->ssl_arg);
+ report_errors(ssl);
+ SSL_free(ssl);
vio->ssl_arg= 0;
- vio_reset(vio, old_type,vio->sd,0,FALSE);
+ vio_reset(vio, old_type, vio->sd, 0, FALSE);
vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1);
- }
+ }
#ifndef DBUG_OFF
- DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
- ,SSL_get_cipher_name((SSL*) vio->ssl_arg)));
- server_cert = SSL_get_peer_certificate ((SSL*) vio->ssl_arg);
- if (server_cert != NULL)
{
- DBUG_PRINT("info",("Server certificate:"));
- str = X509_NAME_oneline (X509_get_subject_name (server_cert), 0, 0);
- DBUG_PRINT("info",("\t subject: %s", str));
- free(str);
-
- str = X509_NAME_oneline (X509_get_issuer_name (server_cert), 0, 0);
- 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 (server_cert);
+ X509 *server_cert;
+ DBUG_PRINT("info",("cipher_name: '%s'" , SSL_get_cipher_name(ssl)));
+
+ if ((server_cert= SSL_get_peer_certificate (ssl)))
+ {
+ char buf[256];
+ DBUG_PRINT("info",("Server certificate:"));
+ X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf));
+ DBUG_PRINT("info",("\t subject: %s", buf));
+ X509_NAME_oneline (X509_get_issuer_name(server_cert), buf, sizeof(buf));
+ DBUG_PRINT("info",("\t issuer: %s", buf));
+ X509_free (server_cert);
+ }
+ else
+ DBUG_PRINT("info",("Server does not have certificate."));
}
- else
- DBUG_PRINT("info",("Server does not have certificate."));
#endif
+
DBUG_RETURN(0);
}
-int vio_ssl_blocking(Vio * vio __attribute__((unused)),
+int vio_ssl_blocking(Vio *vio __attribute__((unused)),
my_bool set_blocking_mode,
my_bool *old_mode)
{
+ /* Mode is always blocking */
+ *old_mode= 1;
/* Return error if we try to change to non_blocking mode */
- *old_mode=1; /* Mode is always blocking */
- return set_blocking_mode ? 0 : 1;
+ return (set_blocking_mode ? 0 : 1);
}
-
-void vio_ssl_timeout(Vio *vio __attribute__((unused)),
- uint which __attribute__((unused)),
- uint timeout __attribute__((unused)))
-{
-#ifdef __WIN__
- ulong wait_timeout= (ulong) timeout * 1000;
- (void) setsockopt(vio->sd, SOL_SOCKET,
- which ? SO_SNDTIMEO : SO_RCVTIMEO, (char*) &wait_timeout,
- sizeof(wait_timeout));
-#endif /* __WIN__ */
-}
#endif /* HAVE_OPENSSL */
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index 002874caf58..af2118417b2 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -21,7 +21,6 @@
static bool ssl_algorithms_added = FALSE;
static bool ssl_error_strings_loaded= FALSE;
static int verify_depth = 0;
-static int verify_error = X509_V_OK;
static unsigned char dh512_p[]=
{
@@ -82,30 +81,31 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
DBUG_ENTER("vio_set_cert_stuff");
DBUG_PRINT("enter", ("ctx: %p, cert_file: %s, key_file: %s",
ctx, cert_file, key_file));
- if (cert_file != NULL)
+ if (cert_file)
{
- if (SSL_CTX_use_certificate_file(ctx,cert_file,SSL_FILETYPE_PEM) <= 0)
+ if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0)
{
- DBUG_PRINT("error",("unable to get certificate from '%s'\n",cert_file));
+ DBUG_PRINT("error",("unable to get certificate from '%s'\n", cert_file));
/* FIX stderr */
fprintf(stderr,"Error when connection to server using SSL:");
ERR_print_errors_fp(stderr);
fprintf(stderr,"Unable to get certificate from '%s'\n", cert_file);
fflush(stderr);
- DBUG_RETURN(0);
+ DBUG_RETURN(1);
}
- if (key_file == NULL)
- key_file = cert_file;
- if (SSL_CTX_use_PrivateKey_file(ctx,key_file,
- SSL_FILETYPE_PEM) <= 0)
+
+ if (!key_file)
+ key_file= cert_file;
+
+ if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0)
{
- DBUG_PRINT("error", ("unable to get private key from '%s'\n",key_file));
+ DBUG_PRINT("error", ("unable to get private key from '%s'\n", key_file));
/* FIX stderr */
fprintf(stderr,"Error when connection to server using SSL:");
ERR_print_errors_fp(stderr);
- fprintf(stderr,"Unable to get private key from '%s'\n", cert_file);
- fflush(stderr);
- DBUG_RETURN(0);
+ fprintf(stderr,"Unable to get private key from '%s'\n", key_file);
+ fflush(stderr);
+ DBUG_RETURN(1);
}
/*
@@ -116,45 +116,45 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
{
DBUG_PRINT("error",
("Private key does not match the certificate public key\n"));
- DBUG_RETURN(0);
+ DBUG_RETURN(1);
}
}
- DBUG_RETURN(1);
+ DBUG_RETURN(0);
}
static int
vio_verify_callback(int ok, X509_STORE_CTX *ctx)
{
- char buf[256];
- X509* err_cert;
- int err,depth;
+ char buf[256];
+ X509 *err_cert;
DBUG_ENTER("vio_verify_callback");
- DBUG_PRINT("enter", ("ok: %d, ctx: 0x%p", ok, ctx));
- err_cert=X509_STORE_CTX_get_current_cert(ctx);
- err= X509_STORE_CTX_get_error(ctx);
- depth= X509_STORE_CTX_get_error_depth(ctx);
+ DBUG_PRINT("enter", ("ok: %d, ctx: %p", ok, ctx));
- X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf));
+ err_cert= X509_STORE_CTX_get_current_cert(ctx);
+ X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
+ DBUG_PRINT("info", ("cert: %s", buf));
if (!ok)
{
- DBUG_PRINT("error",("verify error: num: %d : '%s'\n",err,
+ int err, depth;
+ err= X509_STORE_CTX_get_error(ctx);
+ depth= X509_STORE_CTX_get_error_depth(ctx);
+
+ DBUG_PRINT("error",("verify error: %d, '%s'",err,
X509_verify_cert_error_string(err)));
+ /*
+ Approve cert if depth is greater then "verify_depth", currently
+ verify_depth is always 0 and there is no way to increase it.
+ */
if (verify_depth >= depth)
- {
- ok=1;
- verify_error=X509_V_OK;
- }
- else
- {
- verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
- }
+ ok= 1;
}
- switch (ctx->error) {
+ switch (ctx->error)
+ {
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
- X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
- DBUG_PRINT("info",("issuer= %s\n",buf));
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
+ DBUG_PRINT("info",("issuer= %s\n", buf));
break;
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
@@ -198,198 +198,155 @@ static void netware_ssl_init()
#endif /* __NETWARE__ */
-/************************ VioSSLConnectorFd **********************************/
-/*
- TODO:
- Add option --verify to mysql to be able to change verification mode
-*/
-
-struct st_VioSSLConnectorFd *
-new_VioSSLConnectorFd(const char* key_file,
- const char* cert_file,
- const char* ca_file,
- const char* ca_path,
- const char* cipher)
+static void check_ssl_init()
{
- int verify = SSL_VERIFY_NONE;
- struct st_VioSSLConnectorFd* ptr;
- int result;
- DH *dh;
- DBUG_ENTER("new_VioSSLConnectorFd");
-
- if (!(ptr=((struct st_VioSSLConnectorFd*)
- my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0)))))
- DBUG_RETURN(0);
-
- ptr->ssl_context= 0;
- ptr->ssl_method= 0;
- /* FIXME: constants! */
-
if (!ssl_algorithms_added)
{
- DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
- ssl_algorithms_added = TRUE;
+ ssl_algorithms_added= TRUE;
SSL_library_init();
OpenSSL_add_all_algorithms();
+
}
+
#ifdef __NETWARE__
netware_ssl_init();
#endif
if (!ssl_error_strings_loaded)
{
- DBUG_PRINT("info", ("todo:SSL_load_error_strings()"));
- ssl_error_strings_loaded = TRUE;
+ ssl_error_strings_loaded= TRUE;
SSL_load_error_strings();
}
- ptr->ssl_method = TLSv1_client_method();
- ptr->ssl_context = SSL_CTX_new(ptr->ssl_method);
- DBUG_PRINT("info", ("ssl_context: %p",ptr->ssl_context));
- if (ptr->ssl_context == 0)
+}
+
+/************************ VioSSLFd **********************************/
+static struct st_VioSSLFd *
+new_VioSSLFd(const char *key_file, const char *cert_file,
+ const char *ca_file, const char *ca_path,
+ const char *cipher, SSL_METHOD *method)
+{
+ DH *dh;
+ struct st_VioSSLFd *ssl_fd;
+ DBUG_ENTER("new_VioSSLFd");
+
+ check_ssl_init();
+
+ if (!(ssl_fd= ((struct st_VioSSLFd*)
+ my_malloc(sizeof(struct st_VioSSLFd),MYF(0)))))
+ DBUG_RETURN(0);
+
+ if (!(ssl_fd->ssl_context= SSL_CTX_new(method)))
{
DBUG_PRINT("error", ("SSL_CTX_new failed"));
report_errors();
- goto ctor_failure;
- }
- /*
- SSL_CTX_set_options
- SSL_CTX_set_info_callback
- */
- if (cipher)
- {
- result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher);
- DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
+ my_free((void*)ssl_fd,MYF(0));
+ DBUG_RETURN(0);
}
- SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback);
- if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1)
+
+ /* Set the ciphers that can be used */
+ if (cipher && SSL_CTX_set_cipher_list(ssl_fd->ssl_context, cipher))
{
- DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
+ DBUG_PRINT("error", ("failed to set ciphers to use"));
report_errors();
- goto ctor_failure;
+ my_free((void*)ssl_fd,MYF(0));
+ DBUG_RETURN(0);
}
- if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file,ca_path) == 0)
+
+ /* Load certs from the trusted ca */
+ if (SSL_CTX_load_verify_locations(ssl_fd->ssl_context, ca_file, ca_path) == 0)
{
DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
- if (SSL_CTX_set_default_verify_paths(ptr->ssl_context) == 0)
+ if (SSL_CTX_set_default_verify_paths(ssl_fd->ssl_context) == 0)
{
DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
report_errors();
- goto ctor_failure;
+ my_free((void*)ssl_fd,MYF(0));
+ DBUG_RETURN(0);
}
- }
+ }
+
+ if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file))
+ {
+ DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
+ report_errors();
+ my_free((void*)ssl_fd,MYF(0));
+ DBUG_RETURN(0);
+ }
/* DH stuff */
dh=get_dh512();
- SSL_CTX_set_tmp_dh(ptr->ssl_context,dh);
+ SSL_CTX_set_tmp_dh(ssl_fd->ssl_context, dh);
DH_free(dh);
- DBUG_RETURN(ptr);
-ctor_failure:
- DBUG_PRINT("exit", ("there was an error"));
- my_free((gptr)ptr,MYF(0));
- DBUG_RETURN(0);
+ DBUG_PRINT("exit", ("OK 1"));
+
+ DBUG_RETURN(ssl_fd);
}
-/************************ VioSSLAcceptorFd **********************************/
-/*
- TODO:
- Add option --verify to mysqld to be able to change verification mode
-*/
-struct st_VioSSLAcceptorFd *
-new_VioSSLAcceptorFd(const char *key_file,
- const char *cert_file,
- const char *ca_file,
- const char *ca_path,
- const char *cipher)
+/************************ VioSSLConnectorFd **********************************/
+struct st_VioSSLFd *
+new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
+ const char *ca_file, const char *ca_path,
+ const char *cipher)
{
- int verify = (SSL_VERIFY_PEER |
- SSL_VERIFY_CLIENT_ONCE);
- struct st_VioSSLAcceptorFd* ptr;
- int result;
- DH *dh;
- DBUG_ENTER("new_VioSSLAcceptorFd");
+ struct st_VioSSLFd *ssl_fd;
+ int verify= SSL_VERIFY_PEER;
+ if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
+ ca_path, cipher, TLSv1_client_method())))
+ {
+ return 0;
+ }
- ptr= ((struct st_VioSSLAcceptorFd*)
- my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0)));
- ptr->ssl_context=0;
- ptr->ssl_method=0;
- /* FIXME: constants! */
- ptr->session_id_context= ptr;
+ /* Init the VioSSLFd as a "connector" ie. the client side */
- if (!ssl_algorithms_added)
- {
- DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
- ssl_algorithms_added = TRUE;
- SSL_library_init();
- OpenSSL_add_all_algorithms();
+ /*
+ The verify_callback function is used to control the behaviour
+ when the SSL_VERIFY_PEER flag is set.
+ */
+ SSL_CTX_set_verify(ssl_fd->ssl_context, verify, vio_verify_callback);
- }
-#ifdef __NETWARE__
- netware_ssl_init();
-#endif
+ return ssl_fd;
+}
- if (!ssl_error_strings_loaded)
- {
- DBUG_PRINT("info", ("todo: SSL_load_error_strings()"));
- ssl_error_strings_loaded = TRUE;
- SSL_load_error_strings();
- }
- ptr->ssl_method= TLSv1_server_method();
- ptr->ssl_context= SSL_CTX_new(ptr->ssl_method);
- if (ptr->ssl_context == 0)
- {
- DBUG_PRINT("error", ("SSL_CTX_new failed"));
- report_errors();
- goto ctor_failure;
- }
- if (cipher)
+
+/************************ VioSSLAcceptorFd **********************************/
+struct st_VioSSLFd*
+new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
+ const char *ca_file, const char *ca_path,
+ const char *cipher)
+{
+ struct st_VioSSLFd *ssl_fd;
+ int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
+ if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
+ ca_path, cipher, TLSv1_server_method())))
{
- result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher);
- DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
+ return 0;
}
- /* SSL_CTX_set_quiet_shutdown(ctx,1); */
- SSL_CTX_sess_set_cache_size(ptr->ssl_context,128);
+ /* Init the the VioSSLFd as a "acceptor" ie. the server side */
- /* DH? */
- SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback);
- SSL_CTX_set_session_id_context(ptr->ssl_context,
- (const uchar*) &(ptr->session_id_context),
- sizeof(ptr->session_id_context));
+ /* Set max number of cached sessions, returns the previous size */
+ SSL_CTX_sess_set_cache_size(ssl_fd->ssl_context, 128);
/*
- SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
+ The verify_callback function is used to control the behaviour
+ when the SSL_VERIFY_PEER flag is set.
*/
- if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1)
- {
- DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
- report_errors();
- goto ctor_failure;
- }
- if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file, ca_path) == 0)
- {
- DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
- if (SSL_CTX_set_default_verify_paths(ptr->ssl_context)==0)
- {
- DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
- report_errors();
- goto ctor_failure;
- }
- }
- /* DH stuff */
- dh=get_dh512();
- SSL_CTX_set_tmp_dh(ptr->ssl_context,dh);
- DH_free(dh);
- DBUG_RETURN(ptr);
+ SSL_CTX_set_verify(ssl_fd->ssl_context, verify, vio_verify_callback);
-ctor_failure:
- DBUG_PRINT("exit", ("there was an error"));
- my_free((gptr) ptr,MYF(0));
- DBUG_RETURN(0);
+ /*
+ Set session_id - an identifier for this server session
+ Use the ssl_fd pointer
+ */
+ SSL_CTX_set_session_id_context(ssl_fd->ssl_context,
+ (const unsigned char *)ssl_fd,
+ sizeof(ssl_fd));
+
+ return ssl_fd;
}
-void free_vio_ssl_acceptor_fd(struct st_VioSSLAcceptorFd *fd)
+void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd)
{
SSL_CTX_free(fd->ssl_context);
my_free((gptr) fd, MYF(0));