mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge neptunus.(none):/home/msvensson/mysql/bug17208/my50-bug17208
into neptunus.(none):/home/msvensson/mysql/mysql-5.0-maint
This commit is contained in:
commit
31db4898c3
20 changed files with 433 additions and 544 deletions
|
@ -1,13 +1,14 @@
|
|||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 2 (0x2)
|
||||
Serial Number:
|
||||
e9:07:d1:01:94:ee:66:ca
|
||||
Signature Algorithm: md5WithRSAEncryption
|
||||
Issuer: C=SE, L=Uppsala, O=MySQL AB, CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
|
||||
Issuer: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer@mysql.com
|
||||
Validity
|
||||
Not Before: Sep 12 16:22:06 2003 GMT
|
||||
Not After : Sep 9 16:22:06 2013 GMT
|
||||
Subject: C=SE, L=Uppsala, O=MySQL AB, CN=MySQL Server/Email=abstract.mysql.developer@mysql.com
|
||||
Not Before: Apr 18 15:35:37 2006 GMT
|
||||
Not After : Jan 12 15:35:37 2009 GMT
|
||||
Subject: C=SE, ST=Uppsala, L=Uppsala, O=MySQL AB, CN=localhost/emailAddress=abstract.mysql.developer@mysql.com
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
RSA Public Key: (1024 bit)
|
||||
|
@ -23,45 +24,42 @@ Certificate:
|
|||
3d:0e:4d:2a:a8:b8:ca:99:8d
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Netscape Comment:
|
||||
OpenSSL Generated Certificate
|
||||
X509v3 Subject Key Identifier:
|
||||
6E:E4:9B:6A:C5:EA:E4:E6:C7:EF:D7:1E:C8:63:45:60:2B:1B:D4:D4
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:88:98:65:D9:F3:F2:8B:03:1D:66:60:61:23:FA:AD:73:6D:D3:68:92
|
||||
DirName:/C=SE/L=Uppsala/O=MySQL AB/CN=Abstract MySQL Developer/Email=abstract.mysql.developer@mysql.com
|
||||
serial:00
|
||||
keyid:6E:E4:9B:6A:C5:EA:E4:E6:C7:EF:D7:1E:C8:63:45:60:2B:1B:D4:D4
|
||||
DirName:/C=SE/ST=Uppsala/L=Uppsala/O=MySQL AB/CN=localhost/emailAddress=abstract.mysql.developer@mysql.com
|
||||
serial:E9:07:D1:01:94:EE:66:CA
|
||||
|
||||
X509v3 Basic Constraints:
|
||||
CA:TRUE
|
||||
Signature Algorithm: md5WithRSAEncryption
|
||||
31:77:69:b9:bd:ab:29:f3:fc:5a:09:16:6f:5d:42:ea:ba:01:
|
||||
55:69:e3:75:cf:b8:d1:b7:b9:bf:da:63:85:8c:48:92:06:60:
|
||||
76:97:e0:00:78:4b:ad:da:ab:6a:90:6d:8b:03:a8:b1:e9:09:
|
||||
78:e1:29:98:56:12:60:6b:42:fe:e8:a7:c4:f8:d6:15:07:e8:
|
||||
2b:c2:d8:8a:e5:1b:2e:51:08:9b:56:e3:b3:7a:4c:3e:e5:be:
|
||||
4a:4d:f8:65:7b:a8:21:e0:ca:fe:8b:ab:d7:ec:f2:2d:f7:d0:
|
||||
bf:d7:c5:23:1c:08:d8:aa:57:c7:f3:5f:ba:33:3f:78:d1:f4:
|
||||
8e:5e
|
||||
1f:03:59:6e:ff:1f:9d:c7:19:9e:8e:b2:1a:c0:0b:9e:ee:94:
|
||||
35:77:2a:93:04:ea:d5:a8:fc:36:5a:5b:e3:1c:02:b8:cf:04:
|
||||
6e:21:b0:27:f6:96:6e:d6:8f:cd:02:cf:23:f3:e7:ff:6a:ee:
|
||||
a9:09:c5:c9:07:81:b6:d2:bc:bd:13:47:0d:7b:76:f6:8a:c4:
|
||||
76:24:f8:4c:4e:26:fc:d8:c0:1f:3d:40:19:43:8e:41:ab:99:
|
||||
3a:99:9b:24:7c:ae:78:f3:df:2f:a2:ed:8f:27:0a:0a:0b:04:
|
||||
bf:25:74:88:87:96:c8:68:d5:bc:5b:a0:ef:14:aa:53:6e:c4:
|
||||
a3:e3
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDkTCCAvqgAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBiDELMAkGA1UEBhMCU0Ux
|
||||
EDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMSEwHwYDVQQDExhB
|
||||
YnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAvBgkqhkiG9w0BCQEWImFic3RyYWN0
|
||||
Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb20wHhcNMDMwOTEyMTYyMjA2WhcNMTMw
|
||||
OTA5MTYyMjA2WjB8MQswCQYDVQQGEwJTRTEQMA4GA1UEBxMHVXBwc2FsYTERMA8G
|
||||
A1UEChMITXlTUUwgQUIxFTATBgNVBAMTDE15U1FMIFNlcnZlcjExMC8GCSqGSIb3
|
||||
DQEJARYiYWJzdHJhY3QubXlzcWwuZGV2ZWxvcGVyQG15c3FsLmNvbTCBnzANBgkq
|
||||
hkiG9w0BAQEFAAOBjQAwgYkCgYEA6YZ6VYSITL6k+JJzMBJJC3qFhzk0OQ19C40Y
|
||||
wheVE1LSP1UQV8g/WvWy+ovQZ0nMqoL8n84AtHPzNtI608KwDhTD1LIhdKHwMYFg
|
||||
h5hzXBDBsRpN8fOwmD/w15ebK/3VIXmyL+tkFcmbnfyeLdT4BFvqqXVLQsM9Dk0q
|
||||
qLjKmY0CAwEAAaOCARQwggEQMAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9w
|
||||
ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRu5Jtqxerk5sfv
|
||||
1x7IY0VgKxvU1DCBtQYDVR0jBIGtMIGqgBSImGXZ8/KLAx1mYGEj+q1zbdNokqGB
|
||||
jqSBizCBiDELMAkGA1UEBhMCU0UxEDAOBgNVBAcTB1VwcHNhbGExETAPBgNVBAoT
|
||||
CE15U1FMIEFCMSEwHwYDVQQDExhBYnN0cmFjdCBNeVNRTCBEZXZlbG9wZXIxMTAv
|
||||
BgkqhkiG9w0BCQEWImFic3RyYWN0Lm15c3FsLmRldmVsb3BlckBteXNxbC5jb22C
|
||||
AQAwDQYJKoZIhvcNAQEEBQADgYEAMXdpub2rKfP8WgkWb11C6roBVWnjdc+40be5
|
||||
v9pjhYxIkgZgdpfgAHhLrdqrapBtiwOosekJeOEpmFYSYGtC/uinxPjWFQfoK8LY
|
||||
iuUbLlEIm1bjs3pMPuW+Sk34ZXuoIeDK/our1+zyLffQv9fFIxwI2KpXx/NfujM/
|
||||
eNH0jl4=
|
||||
MIIDijCCAvOgAwIBAgIJAOkH0QGU7mbKMA0GCSqGSIb3DQEBBAUAMIGLMQswCQYD
|
||||
VQQGEwJTRTEQMA4GA1UECBMHVXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8G
|
||||
A1UEChMITXlTUUwgQUIxEjAQBgNVBAMTCWxvY2FsaG9zdDExMC8GCSqGSIb3DQEJ
|
||||
ARYiYWJzdHJhY3QubXlzcWwuZGV2ZWxvcGVyQG15c3FsLmNvbTAeFw0wNjA0MTgx
|
||||
NTM1MzdaFw0wOTAxMTIxNTM1MzdaMIGLMQswCQYDVQQGEwJTRTEQMA4GA1UECBMH
|
||||
VXBwc2FsYTEQMA4GA1UEBxMHVXBwc2FsYTERMA8GA1UEChMITXlTUUwgQUIxEjAQ
|
||||
BgNVBAMTCWxvY2FsaG9zdDExMC8GCSqGSIb3DQEJARYiYWJzdHJhY3QubXlzcWwu
|
||||
ZGV2ZWxvcGVyQG15c3FsLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
|
||||
6YZ6VYSITL6k+JJzMBJJC3qFhzk0OQ19C40YwheVE1LSP1UQV8g/WvWy+ovQZ0nM
|
||||
qoL8n84AtHPzNtI608KwDhTD1LIhdKHwMYFgh5hzXBDBsRpN8fOwmD/w15ebK/3V
|
||||
IXmyL+tkFcmbnfyeLdT4BFvqqXVLQsM9Dk0qqLjKmY0CAwEAAaOB8zCB8DAdBgNV
|
||||
HQ4EFgQUbuSbasXq5ObH79ceyGNFYCsb1NQwgcAGA1UdIwSBuDCBtYAUbuSbasXq
|
||||
5ObH79ceyGNFYCsb1NShgZGkgY4wgYsxCzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdV
|
||||
cHBzYWxhMRAwDgYDVQQHEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBBQjESMBAG
|
||||
A1UEAxMJbG9jYWxob3N0MTEwLwYJKoZIhvcNAQkBFiJhYnN0cmFjdC5teXNxbC5k
|
||||
ZXZlbG9wZXJAbXlzcWwuY29tggkA6QfRAZTuZsowDAYDVR0TBAUwAwEB/zANBgkq
|
||||
hkiG9w0BAQQFAAOBgQAfA1lu/x+dxxmejrIawAue7pQ1dyqTBOrVqPw2WlvjHAK4
|
||||
zwRuIbAn9pZu1o/NAs8j8+f/au6pCcXJB4G20ry9E0cNe3b2isR2JPhMTib82MAf
|
||||
PUAZQ45Bq5k6mZskfK54898vou2PJwoKCwS/JXSIh5bIaNW8W6DvFKpTbsSj4w==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
@ -51,5 +51,5 @@ enum options_client
|
|||
#endif
|
||||
OPT_TRIGGERS,
|
||||
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
|
||||
OPT_TZ_UTC, OPT_AUTO_CLOSE
|
||||
OPT_TZ_UTC, OPT_AUTO_CLOSE, OPT_SSL_VERIFY_SERVER_CERT
|
||||
};
|
||||
|
|
|
@ -3125,6 +3125,8 @@ sql_real_connect(char *host,char *database,char *user,char *password,
|
|||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
|
||||
(char*)&opt_ssl_verify_server_cert);
|
||||
#endif
|
||||
if (opt_protocol)
|
||||
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
|
||||
|
|
|
@ -340,6 +340,8 @@ int main(int argc,char *argv[])
|
|||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
|
||||
(char*)&opt_ssl_verify_server_cert);
|
||||
#endif
|
||||
if (opt_protocol)
|
||||
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
|
||||
|
|
|
@ -905,6 +905,8 @@ static int dbConnect(char *host, char *user,char *passwd)
|
|||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
|
||||
(char*)&opt_ssl_verify_server_cert);
|
||||
#endif
|
||||
if (opt_protocol)
|
||||
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
|
||||
|
|
|
@ -384,6 +384,8 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd)
|
|||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
mysql_options(&mysql_connection,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
|
||||
(char*)&opt_ssl_verify_server_cert);
|
||||
#endif
|
||||
if (opt_protocol)
|
||||
mysql_options(&mysql_connection,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
|
||||
|
|
|
@ -109,6 +109,8 @@ int main(int argc, char **argv)
|
|||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
mysql_options(&mysql,MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
|
||||
(char*)&opt_ssl_verify_server_cert);
|
||||
#endif
|
||||
if (opt_protocol)
|
||||
mysql_options(&mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
|
||||
|
|
|
@ -108,7 +108,7 @@ enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
|
|||
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC,
|
||||
OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
|
||||
OPT_SSL_CIPHER,OPT_PS_PROTOCOL,OPT_SP_PROTOCOL,OPT_CURSOR_PROTOCOL,
|
||||
OPT_VIEW_PROTOCOL};
|
||||
OPT_VIEW_PROTOCOL, OPT_SSL_VERIFY_SERVER_CERT};
|
||||
|
||||
/* ************************************************************************ */
|
||||
/*
|
||||
|
@ -2378,8 +2378,12 @@ int do_connect(struct st_query *q)
|
|||
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (opt_use_ssl || con_ssl)
|
||||
{
|
||||
mysql_ssl_set(&next_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
|
||||
&opt_ssl_verify_server_cert);
|
||||
}
|
||||
#endif
|
||||
if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR)
|
||||
con_sock=fn_format(buff, con_sock, TMPDIR, "",0);
|
||||
|
@ -4604,9 +4608,14 @@ int main(int argc, char **argv)
|
|||
mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name);
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
opt_ssl_verify_server_cert= TRUE; /* Always on in mysqltest */
|
||||
if (opt_use_ssl)
|
||||
{
|
||||
mysql_ssl_set(&cur_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
mysql_options(&cur_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT,
|
||||
&opt_ssl_verify_server_cert);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(cur_con->name = my_strdup("default", MYF(MY_WME))))
|
||||
|
|
|
@ -149,7 +149,8 @@ enum mysql_option
|
|||
MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
|
||||
MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
|
||||
MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
|
||||
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT
|
||||
MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
|
||||
MYSQL_OPT_SSL_VERIFY_SERVER_CERT
|
||||
};
|
||||
|
||||
struct st_mysql_options {
|
||||
|
@ -164,6 +165,7 @@ struct st_mysql_options {
|
|||
char *ssl_ca; /* PEM CA file */
|
||||
char *ssl_capath; /* PEM directory of CA-s? */
|
||||
char *ssl_cipher; /* cipher to use */
|
||||
my_bool ssl_verify_server_cert; /* if to verify server cert */
|
||||
char *shared_memory_base_name;
|
||||
unsigned long max_allowed_packet;
|
||||
my_bool use_ssl; /* if to use SSL or not */
|
||||
|
|
|
@ -37,5 +37,10 @@
|
|||
{"ssl-cipher", OPT_SSL_CIPHER, "SSL cipher to use (implies --ssl).",
|
||||
(gptr*) &opt_ssl_cipher, (gptr*) &opt_ssl_cipher, 0, GET_STR, REQUIRED_ARG,
|
||||
0, 0, 0, 0, 0, 0},
|
||||
|
||||
#ifdef MYSQL_CLIENT
|
||||
{"ssl-verify-server-cert", OPT_SSL_VERIFY_SERVER_CERT,
|
||||
"Verify servers \"Common Name\" in it's cert against hostname used when connecting. This option is disabled by default.",
|
||||
(gptr*) &opt_ssl_verify_server_cert, (gptr*) &opt_ssl_verify_server_cert,
|
||||
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#endif
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
|
|
@ -21,4 +21,7 @@ static char *opt_ssl_cert = 0;
|
|||
static char *opt_ssl_ca = 0;
|
||||
static char *opt_ssl_capath = 0;
|
||||
static char *opt_ssl_cipher = 0;
|
||||
#ifdef MYSQL_CLIENT
|
||||
static my_bool opt_ssl_verify_server_cert= 0;
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -105,33 +105,22 @@ void vio_timeout(Vio *vio,uint which, uint timeout);
|
|||
#include <openssl/ssl.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
struct st_VioSSLAcceptorFd
|
||||
struct st_VioSSLFd
|
||||
{
|
||||
SSL_CTX *ssl_context;
|
||||
SSL_METHOD *ssl_method;
|
||||
struct st_VioSSLAcceptorFd *session_id_context;
|
||||
};
|
||||
|
||||
/* One copy for client */
|
||||
struct st_VioSSLConnectorFd
|
||||
{
|
||||
SSL_CTX *ssl_context;
|
||||
/* function pointers which are only once for SSL client */
|
||||
SSL_METHOD *ssl_method;
|
||||
};
|
||||
int sslaccept(struct st_VioSSLFd*, Vio *, long timeout);
|
||||
int sslconnect(struct st_VioSSLFd*, Vio *, long timeout);
|
||||
|
||||
int sslaccept(struct st_VioSSLAcceptorFd*, Vio *, long timeout);
|
||||
int sslconnect(struct st_VioSSLConnectorFd*, Vio *, long timeout);
|
||||
|
||||
struct st_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);
|
||||
struct st_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);
|
||||
Vio *new_VioSSL(struct st_VioSSLAcceptorFd *fd, Vio *sd, int state);
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
#ifdef HAVE_SMEM
|
||||
|
|
|
@ -1500,6 +1500,7 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
|
|||
mysql->options.ssl_ca= strdup_if_not_null(ca);
|
||||
mysql->options.ssl_capath= strdup_if_not_null(capath);
|
||||
mysql->options.ssl_cipher= strdup_if_not_null(cipher);
|
||||
mysql->options.ssl_verify_server_cert= FALSE; /* Off by default */
|
||||
#endif /* HAVE_OPENSSL */
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -1514,17 +1515,16 @@ 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));
|
||||
my_free(mysql->options.ssl_cert, MYF(MY_ALLOW_ZERO_PTR));
|
||||
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);
|
||||
my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
|
||||
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;
|
||||
|
@ -1556,6 +1556,77 @@ mysql_get_ssl_cipher(MYSQL *mysql)
|
|||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check the server's (subject) Common Name against the
|
||||
hostname we connected to
|
||||
|
||||
SYNOPSIS
|
||||
ssl_verify_server_cert()
|
||||
vio pointer to a SSL connected vio
|
||||
server_hostname name of the server that we connected to
|
||||
|
||||
RETURN VALUES
|
||||
0 Success
|
||||
1 Failed to validate server
|
||||
|
||||
*/
|
||||
static int ssl_verify_server_cert(Vio *vio, const char* server_hostname)
|
||||
{
|
||||
SSL *ssl;
|
||||
X509 *server_cert;
|
||||
char *cp1, *cp2;
|
||||
char buf[256];
|
||||
DBUG_ENTER("ssl_verify_server_cert");
|
||||
DBUG_PRINT("enter", ("server_hostname: %s", server_hostname));
|
||||
|
||||
if (!(ssl= (SSL*)vio->ssl_arg))
|
||||
{
|
||||
DBUG_PRINT("error", ("No SSL pointer found"));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
if (!server_hostname)
|
||||
{
|
||||
DBUG_PRINT("error", ("No server hostname supplied"));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
if (!(server_cert= SSL_get_peer_certificate(ssl)))
|
||||
{
|
||||
DBUG_PRINT("error", ("Could not get server certificate"));
|
||||
DBUG_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);
|
||||
|
||||
DBUG_PRINT("info", ("hostname in cert: %s", buf));
|
||||
cp1 = strstr(buf, "/CN=");
|
||||
if (cp1)
|
||||
{
|
||||
cp1 += 4; // Skip the "/CN=" that we found
|
||||
// Search for next / which might be the delimiter for email
|
||||
cp2 = strchr(cp1, '/');
|
||||
if (cp2)
|
||||
*cp2 = '\0';
|
||||
DBUG_PRINT("info", ("Server hostname in cert: %s", cp1));
|
||||
if (!strcmp(cp1, server_hostname))
|
||||
{
|
||||
/* Success */
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
}
|
||||
DBUG_PRINT("error", ("SSL certificate validation failure"));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
|
||||
|
@ -1589,7 +1660,6 @@ static MYSQL_METHODS client_methods=
|
|||
#endif
|
||||
};
|
||||
|
||||
|
||||
MYSQL *
|
||||
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
|
||||
const char *passwd, const char *db,
|
||||
|
@ -2034,37 +2104,52 @@ 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!"));
|
||||
|
||||
/* Verify server cert */
|
||||
if (mysql->options.ssl_verify_server_cert &&
|
||||
ssl_verify_server_cert(mysql->net.vio, mysql->host))
|
||||
{
|
||||
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
|
||||
goto error;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
|
@ -2804,6 +2889,9 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg)
|
|||
case MYSQL_OPT_RECONNECT:
|
||||
mysql->reconnect= *(my_bool *) arg;
|
||||
break;
|
||||
case MYSQL_OPT_SSL_VERIFY_SERVER_CERT:
|
||||
mysql->options.ssl_verify_server_cert= *(my_bool *) arg;
|
||||
break;
|
||||
default:
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
|
|
@ -1310,7 +1310,7 @@ extern pthread_t signal_thread;
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
|
||||
extern struct st_VioSSLFd * ssl_acceptor_fd;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
|
||||
|
|
|
@ -620,7 +620,7 @@ static void openssl_lock(int, openssl_lock_t *, const char *, int);
|
|||
static unsigned long openssl_id_function();
|
||||
#endif
|
||||
char *des_key_file;
|
||||
struct st_VioSSLAcceptorFd *ssl_acceptor_fd;
|
||||
struct st_VioSSLFd *ssl_acceptor_fd;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
|
||||
|
@ -1131,7 +1131,10 @@ void clean_up(bool print_message)
|
|||
#endif
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (ssl_acceptor_fd)
|
||||
my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR));
|
||||
{
|
||||
SSL_CTX_free(ssl_acceptor_fd->ssl_context);
|
||||
my_free((gptr) ssl_acceptor_fd, MYF(0));
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
#ifdef USE_REGEX
|
||||
my_regex_end();
|
||||
|
|
|
@ -858,8 +858,8 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
|
|||
if (acl_user->x509_issuer)
|
||||
{
|
||||
DBUG_PRINT("info",("checkpoint 3"));
|
||||
char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
|
||||
DBUG_PRINT("info",("comparing issuers: '%s' and '%s'",
|
||||
char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
|
||||
DBUG_PRINT("info",("comparing issuers: '%s' and '%s'",
|
||||
acl_user->x509_issuer, ptr));
|
||||
if (strcmp(acl_user->x509_issuer, ptr))
|
||||
{
|
||||
|
|
16
vio/vio.c
16
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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
360
vio/viossl.c
360
vio/viossl.c
|
@ -54,12 +54,12 @@ static void
|
|||
report_errors()
|
||||
{
|
||||
unsigned long l;
|
||||
const char* file;
|
||||
const char* data;
|
||||
int line,flags;
|
||||
const char *file;
|
||||
const char *data;
|
||||
int line,flags;
|
||||
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),
|
||||
|
@ -70,13 +70,7 @@ report_errors()
|
|||
}
|
||||
|
||||
|
||||
int vio_ssl_errno(Vio *vio __attribute__((unused)))
|
||||
{
|
||||
return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
|
@ -94,7 +88,7 @@ int vio_ssl_read(Vio * vio, gptr buf, int size)
|
|||
}
|
||||
|
||||
|
||||
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");
|
||||
|
@ -107,183 +101,51 @@ int vio_ssl_write(Vio * vio, const gptr buf, int size)
|
|||
}
|
||||
|
||||
|
||||
int vio_ssl_fastsend(Vio * vio __attribute__((unused)))
|
||||
int vio_ssl_close(Vio *vio)
|
||||
{
|
||||
int r=0;
|
||||
DBUG_ENTER("vio_ssl_fastsend");
|
||||
|
||||
#if defined(IPTOS_THROUGHPUT) && !defined(__EMX__)
|
||||
{
|
||||
int tos= IPTOS_THROUGHPUT;
|
||||
r= setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos));
|
||||
}
|
||||
#endif /* IPTOS_THROUGHPUT && !__EMX__ */
|
||||
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;
|
||||
}
|
||||
DBUG_PRINT("exit", ("%d", r));
|
||||
DBUG_RETURN(r);
|
||||
}
|
||||
|
||||
|
||||
int vio_ssl_keepalive(Vio* vio, my_bool set_keep_alive)
|
||||
{
|
||||
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)
|
||||
|
||||
if (ssl)
|
||||
{
|
||||
r = SSL_shutdown((SSL*) vio->ssl_arg);
|
||||
SSL_free((SSL*) vio->ssl_arg);
|
||||
switch ((r= SSL_shutdown(ssl)))
|
||||
{
|
||||
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;
|
||||
}
|
||||
SSL_free(ssl);
|
||||
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);
|
||||
DBUG_RETURN(vio_close(vio));
|
||||
}
|
||||
|
||||
|
||||
const char *vio_ssl_description(Vio * vio)
|
||||
int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
|
||||
{
|
||||
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
|
||||
{
|
||||
size_socket addrLen = sizeof(struct sockaddr);
|
||||
if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
|
||||
&addrLen) != 0)
|
||||
{
|
||||
DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
#ifdef TO_BE_FIXED
|
||||
my_inet_ntoa(vio->remote.sin_addr,buf);
|
||||
*port= 0;
|
||||
#else
|
||||
strmov(buf, "unknown");
|
||||
*port= 0;
|
||||
#endif
|
||||
}
|
||||
DBUG_PRINT("exit", ("addr: %s", buf));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
void vio_ssl_in_addr(Vio *vio, struct in_addr *in)
|
||||
{
|
||||
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;
|
||||
X509 *client_cert;
|
||||
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();
|
||||
|
@ -291,144 +153,126 @@ int sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout)
|
|||
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);
|
||||
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];
|
||||
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);
|
||||
X509_NAME_oneline (X509_get_issuer_name (client_cert),
|
||||
buf, sizeof(buf));
|
||||
DBUG_PRINT("info",("\t issuer: %s", buf));
|
||||
|
||||
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!"));
|
||||
}
|
||||
else
|
||||
DBUG_PRINT("info",("Client does not have certificate."));
|
||||
|
||||
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!"));
|
||||
}
|
||||
|
||||
#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;
|
||||
X509 *server_cert;
|
||||
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);
|
||||
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);
|
||||
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",("cipher_name: '%s'" , SSL_get_cipher_name(ssl)));
|
||||
|
||||
if ((server_cert= SSL_get_peer_certificate (ssl)))
|
||||
{
|
||||
char buf[256];
|
||||
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_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."));
|
||||
#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 */
|
||||
|
|
|
@ -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);
|
||||
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,193 +198,149 @@ 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 **********************************/
|
||||
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;
|
||||
my_free((void*)ssl_fd,MYF(0));
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
/*
|
||||
SSL_CTX_set_options
|
||||
SSL_CTX_set_info_callback
|
||||
*/
|
||||
if (cipher)
|
||||
|
||||
/* Set the ciphers that can be used */
|
||||
if (cipher && SSL_CTX_set_cipher_list(ssl_fd->ssl_context, cipher))
|
||||
{
|
||||
result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher);
|
||||
DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
|
||||
DBUG_PRINT("error", ("failed to set ciphers to use"));
|
||||
report_errors();
|
||||
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)
|
||||
|
||||
if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file))
|
||||
{
|
||||
DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
|
||||
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)
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
|
||||
/************************ 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* Init the the VioSSLFd as a "connector" ie. the client side */
|
||||
|
||||
/*
|
||||
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);
|
||||
|
||||
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,
|
||||
struct st_VioSSLFd*
|
||||
new_VioSSLAcceptorFd(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");
|
||||
|
||||
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;
|
||||
|
||||
if (!ssl_algorithms_added)
|
||||
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())))
|
||||
{
|
||||
DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
|
||||
ssl_algorithms_added = TRUE;
|
||||
SSL_library_init();
|
||||
OpenSSL_add_all_algorithms();
|
||||
return 0;
|
||||
}
|
||||
/* Init the the VioSSLFd as a "acceptor" ie. the server side */
|
||||
|
||||
}
|
||||
#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_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)
|
||||
{
|
||||
result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher);
|
||||
DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
|
||||
}
|
||||
/* SSL_CTX_set_quiet_shutdown(ctx,1); */
|
||||
SSL_CTX_sess_set_cache_size(ptr->ssl_context,128);
|
||||
|
||||
/* 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,
|
||||
ssl_fd,
|
||||
sizeof(ssl_fd));
|
||||
|
||||
return ssl_fd;
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
|
Loading…
Reference in a new issue