diff options
author | unknown <msvensson@neptunus.(none)> | 2006-03-10 16:41:14 +0100 |
---|---|---|
committer | unknown <msvensson@neptunus.(none)> | 2006-03-10 16:41:14 +0100 |
commit | b2d5243e97b7395d38bd6afc4767199703cf7f7c (patch) | |
tree | 9de9174f30edd59e8d180336d9b764255478a2f1 /sql-common | |
parent | 91b3447c2d8f87f104f9772557302c662f7f0cb2 (diff) | |
download | mariadb-git-b2d5243e97b7395d38bd6afc4767199703cf7f7c.tar.gz |
Cleanup SSL implementation
Remove duplicate code
Merge common functions
Enforce MySQL coding standard
include/violite.h:
Cleanup SSL implementation
sql-common/client.c:
Cleanup SSL implementation
sql/mysql_priv.h:
Cleanup SSL implementation
sql/mysqld.cc:
Cleanup SSL implementation
sql/sql_acl.cc:
Cleanup SSL implementation
vio/vio.c:
Cleanup SSL implementation
vio/vio_priv.h:
Cleanup SSL implementation
vio/viossl.c:
Cleanup SSL implementation
vio/viosslfactories.c:
Cleanup SSL implementation
Diffstat (limited to 'sql-common')
-rw-r--r-- | sql-common/client.c | 106 |
1 files changed, 89 insertions, 17 deletions
diff --git a/sql-common/client.c b/sql-common/client.c index 2d826df0662..21eb58adf01 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1514,8 +1514,7 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , static void mysql_ssl_free(MYSQL *mysql __attribute__((unused))) { - struct st_VioSSLConnectorFd *st= - (struct st_VioSSLConnectorFd*) mysql->connector_fd; + struct st_VioSSLFd *ssl_fd= (struct st_VioSSLFd*) mysql->connector_fd; DBUG_ENTER("mysql_ssl_free"); my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR)); @@ -1523,8 +1522,8 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused))) my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); - if (st) - SSL_CTX_free(st->ssl_context); + if (ssl_fd) + SSL_CTX_free(ssl_fd->ssl_context); my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR)); mysql->options.ssl_key = 0; mysql->options.ssl_cert = 0; @@ -1568,6 +1567,63 @@ static MYSQL_METHODS client_methods= #endif }; +int ssl_verify_server_cert(Vio *vio, const char* server_host) +{ + SSL *ssl; + X509 *server_cert; + char *cp1, *cp2; + char buf[256]; + DBUG_ENTER("ssl_verify_server_cert"); + DBUG_PRINT("enter", ("server_host: %s", server_host)); + + if (!(ssl= (SSL*)vio->ssl_arg)) + { + DBUG_PRINT("error", ("No SSL pointer found")); + return 1; + } + + if (!server_host) + { + DBUG_PRINT("error", ("No server hostname supplied")); + return 1; + } + + if (!(server_cert= SSL_get_peer_certificate(ssl))) + { + DBUG_PRINT("error", ("Could not get server certificate")); + return 1; + } + + /* + We already know that the certificate exchanged was valid; the SSL library + handled that. Now we need to verify that the contents of the certificate + are what we expect. + */ + + X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf)); + X509_free (server_cert); + +// X509_NAME_get_text_by_NID(x509_get_subject_name(server_cert), NID_commonName, buf, sizeof(buf));... does the same thing + + DBUG_PRINT("info", ("hostname in cert: %s", buf)); + cp1 = strstr(buf, "/CN="); + if (cp1) + { + cp1 += 4; // Skip the "/CN=" that we found + cp2 = strchr(cp1, '/'); + if (cp2) + *cp2 = '\0'; + DBUG_PRINT("info", ("Server hostname in cert: ", cp1)); + if (!strcmp(cp1, server_host)) + { + /* Success */ + DBUG_RETURN(0); + } + } + DBUG_PRINT("error", ("SSL certificate validation failure")); + DBUG_RETURN(1); +} + MYSQL * CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, @@ -2013,37 +2069,53 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->client_flag=client_flag; #ifdef HAVE_OPENSSL - /* - Oops.. are we careful enough to not send ANY information without - encryption? - */ if (client_flag & CLIENT_SSL) { + /* Do the SSL layering. */ struct st_mysql_options *options= &mysql->options; + struct st_VioSSLFd *ssl_fd; + + /* + Send client_flag, max_packet_size - unencrypted otherwise + the server does not know we want to do SSL + */ if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net)) { set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate); goto error; } - /* Do the SSL layering. */ - if (!(mysql->connector_fd= - (gptr) new_VioSSLConnectorFd(options->ssl_key, - options->ssl_cert, - options->ssl_ca, - options->ssl_capath, - options->ssl_cipher))) + + /* Create the VioSSLConnectorFd - init SSL and load certs */ + if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key, + options->ssl_cert, + options->ssl_ca, + options->ssl_capath, + options->ssl_cipher))) { set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); goto error; } + mysql->connector_fd= (void*)ssl_fd; + + /* Connect to the server */ DBUG_PRINT("info", ("IO layer change in progress...")); - if (sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd), - mysql->net.vio, (long) (mysql->options.connect_timeout))) + if (sslconnect(ssl_fd, mysql->net.vio, + (long) (mysql->options.connect_timeout))) { set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); goto error; } DBUG_PRINT("info", ("IO layer change done!")); + +#if 0 + /* Verify server cert */ + if (mysql->options.ssl_verify_cert && + ssl_verify_server_cert(mysql->net.vio, mysql->host)) + { + set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); + goto error; + } +#endif } #endif /* HAVE_OPENSSL */ |