SSL compiles and works as far as can see. Continue testing..
Docs/manual.ja.texi: e-mail address fixed include/mysqld_error.h: Added 3 new errormessages related to SSL mysql-test/install_test_db.sh: SSL fix scripts/mysql_install_db.sh: mysql.user table changes to conform SSL ACL sql/lex.h: Fixed GRANT+SSL clause sql/share/czech/errmsg.txt: Added 3 new errormessages related to SSL sql/share/danish/errmsg.txt: Added 3 new errormessages related to SSL sql/share/dutch/errmsg.txt: Added 3 new errormessages related to SSL sql/share/english/errmsg.txt: Added 3 new errormessages related to SSL sql/share/estonian/errmsg.txt: Added 3 new errormessages related to SSL sql/share/french/errmsg.txt: Added 3 new errormessages related to SSL sql/share/german/errmsg.txt: Added 3 new errormessages related to SSL sql/share/greek/errmsg.txt: Added 3 new errormessages related to SSL sql/share/hungarian/errmsg.txt: Added 3 new errormessages related to SSL sql/share/italian/errmsg.txt: Added 3 new errormessages related to SSL sql/share/japanese/errmsg.txt: Added 3 new errormessages related to SSL sql/share/korean/errmsg.txt: Added 3 new errormessages related to SSL sql/share/norwegian-ny/errmsg.txt: Added 3 new errormessages related to SSL sql/share/norwegian/errmsg.txt: Added 3 new errormessages related to SSL sql/share/polish/errmsg.txt: Added 3 new errormessages related to SSL sql/share/portuguese/errmsg.txt: Added 3 new errormessages related to SSL sql/share/romanian/errmsg.txt: Added 3 new errormessages related to SSL sql/share/russian/errmsg.txt: Added 3 new errormessages related to SSL sql/share/slovak/errmsg.txt: Added 3 new errormessages related to SSL sql/share/spanish/errmsg.txt: Added 3 new errormessages related to SSL sql/share/swedish/errmsg.txt: Added 3 new errormessages related to SSL sql/share/ukrainian/errmsg.txt: Added 3 new errormessages related to SSL Docs/manual.texi: SSL fixes BUILD/compile-pentium-max: SSL was missing here acinclude.m4: typo fix alignment fix client/mysql.cc: SSL fixes client/mysqladmin.c: SSL fixes client/mysqlcheck.c: SSL fixes client/mysqldump.c: SSL fixes client/mysqlimport.c: SSL fixes client/mysqlshow.c: SSL fixes include/mysql.h: SSL fixes include/sslopt-case.h: SSL fixes include/sslopt-longopts.h: SSL fixes include/sslopt-usage.h: SSL fixes include/sslopt-vars.h: SSL fixes include/violite.h: SSL fixes cleanups libmysql/libmysql.c: SSL fixes libmysqld/lib_sql.cc: SSL fixes sql/mini_client.cc: SSL fixes sql/mysqld.cc: SSL fixes cleanup new variables to SHOW STATUS sql/sql_acl.cc: SSL fixes sql/sql_acl.h: SSL fixes sql/sql_lex.h: SSL fixes sql/sql_parse.cc: SSL fixes sql/sql_show.cc: New functions added sql/structs.h: New functions added vio/test-ssl.c: SSL fixes vio/test-sslclient.c: SSL fixes vio/test-sslserver.c: SSL fixes vio/viosocket.c: SSL fixes vio/viossl.c: SSL fixes cleanup vio/viosslfactories.c: SSL fixes sql/sql_yacc.yy: SSL fixes
This commit is contained in:
parent
5e0851e1b3
commit
d13f2dfdeb
@ -8,6 +8,6 @@ extra_configs="$pentium_configs"
|
||||
strip=yes
|
||||
|
||||
extra_configs="$extra_configs --with-innodb --with-berkeley-db \
|
||||
--enable-thread-safe-client"
|
||||
--enable-thread-safe-client --with-openssl --with-vio"
|
||||
|
||||
. "$path/FINISH.sh"
|
||||
|
@ -3187,7 +3187,7 @@ encounter per year, but we are as always very flexible towards our customers!
|
||||
@c @image{Flags/estonia} Estonia [Tradenet] @
|
||||
@c @uref{http://mysql.tradenet.ee, WWW}
|
||||
@item
|
||||
@c EMAIL: tonu@spamm.ee (Tonu Samuel)
|
||||
@c EMAIL: tonu@spam.ee (Tonu Samuel)
|
||||
@image{Flags/estonia} Estonia [OKinteractive] @
|
||||
@uref{http://mysql.mirror.ok.ee, WWW}
|
||||
@item
|
||||
|
130
Docs/manual.texi
130
Docs/manual.texi
@ -15583,7 +15583,7 @@ Users of Java JDBC:
|
||||
Do not transmit plain (unencrypted) data over the Internet. These data are
|
||||
accessible to everyone who has the time and ability to intercept it and use
|
||||
it for their own purposes. Instead, use an encrypted protocol such as SSL or
|
||||
SSH. MySQL supports internal SSL connections as of Version 3.23.9.
|
||||
SSH. MySQL supports internal SSL connections as of Version 4.0.0.
|
||||
SSH port-forwarding can be used to create an encrypted (and compressed)
|
||||
tunnel for the communication.
|
||||
@item
|
||||
@ -16985,7 +16985,11 @@ GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
|
||||
ON @{tbl_name | * | *.* | db_name.*@}
|
||||
TO user_name [IDENTIFIED BY 'password']
|
||||
[, user_name [IDENTIFIED BY 'password'] ...]
|
||||
[REQUIRE @{SSL|X509@} [ISSUER issuer] [SUBJECT subject]]
|
||||
[REQUIRE
|
||||
[@{SSL| X509@}]
|
||||
[CIPHER cipher [AND]]
|
||||
[ISSUER issuer [AND]]
|
||||
[SUBJECT subject]]
|
||||
[WITH GRANT OPTION]
|
||||
|
||||
REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...]
|
||||
@ -17208,6 +17212,120 @@ dropped only with explicit @code{REVOKE} commands or by manipulating the
|
||||
MySQL grant tables.
|
||||
@end itemize
|
||||
|
||||
-----------
|
||||
@cindex SSL and X509 Basics
|
||||
MySQL has support for SSL encrypted connetions. To understand how MySQL uses
|
||||
SSL we need to explain some basics about SSL and X509. People who are already
|
||||
aware of it can skip this chapter.
|
||||
|
||||
By default, MySQL uses unencrypted connections between client and server. This means
|
||||
that anyone on the way can listen and read all your data which moves there. Even
|
||||
more, some people can change content of data while it is moving between client and
|
||||
server. Sometime you may need to move really secret data over public networks and
|
||||
such publicity is unacceptable.
|
||||
|
||||
SSL is a protocol which uses different encryption algorithms to ensure that data
|
||||
which comes from public network can be trusted. It have mechanisms to detect any
|
||||
change, loss or replay of data. SSL also incorpores algorithms to recognize and
|
||||
verification of identity using X509 standard.
|
||||
|
||||
@cindex What is encryption
|
||||
Encryption is the way to make any kind of data unreadable. Even more, today's
|
||||
practice require many additional security elements from encryption algorithms.
|
||||
They should resist many kind of known attacks like just messing with order
|
||||
of encrypted messages or replaying data twice.
|
||||
|
||||
@cindex What is X509/Certificate?
|
||||
X509 is standard which makes possible to identity someone in the Internet. Mostly
|
||||
it is used in e-commerce over the Internet. Shortly speaking there should be some
|
||||
company called "Certificate Authority" which assigns electronic certificates to
|
||||
everyone who needs. Certificates rely on asymmetric encryption algorithms which
|
||||
have two encryption keys - public and secret. Certificate owner can prove his
|
||||
identity showing certificate to other party. Certificate consists his owner public
|
||||
key. Any data encrypted with it can be decrypted only by secret key holder.
|
||||
|
||||
@cindex Possible questions:
|
||||
Q: Why MySQL not uses encrypted connections by default?
|
||||
A: Because it makes MySQL slower. Any kind of additional functionality requires
|
||||
computer to do additional work and encrypting data is CPU-intensive operation which
|
||||
can overcome MySQL own work and consumed time. MySQL is tuned to be fast by default.
|
||||
|
||||
Q: I need more information about SSL/X509/encrpytion/whatever
|
||||
A: Use your favourite internet search engine and search for keywords you are interested in.
|
||||
|
||||
------------
|
||||
|
||||
|
||||
@cindex SSL related options
|
||||
|
||||
MySQL can check x509 certificate attributes additionally to most used username/password
|
||||
cheme. All usual options are still required (username, password, IP address mask, database/table name).
|
||||
|
||||
There are different possibilities to limit connections:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Without any SSL/X509 options all kind of encrypted/unencrypted connections are allowed if
|
||||
username and password are valid.
|
||||
|
||||
@item
|
||||
@code{REQUIRE SSL} option makes SSL encrypted connection must. Note that this requirement
|
||||
can be omitted of there are any other ACL record which allows non-SSL connection.
|
||||
|
||||
Example:
|
||||
@example
|
||||
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SSL
|
||||
@end example
|
||||
|
||||
|
||||
@item
|
||||
* @code{REQUIRE X509} Requiring X509 certificate means that client should have valid certificate
|
||||
but we do not care about exact certificate, issuer or subject. Only restriction is it should
|
||||
be possible to verify its signature with some of our CA certificates.
|
||||
|
||||
Example:
|
||||
@example
|
||||
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE X509
|
||||
@end example
|
||||
|
||||
@item
|
||||
@code{REQUIRE ISSUER issuer} makes connection more restrictive: now client must present
|
||||
valid x509 certificate issued by CA "issuer". Using x509 certificates always implies encryption,
|
||||
so option "SSL" is not neccessary anymore.
|
||||
|
||||
Example:
|
||||
@example
|
||||
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@@mysql.com"
|
||||
@end example
|
||||
|
||||
@item
|
||||
@code{REQUIRE SUBJECT subject} requires client to have valid x509 certificate with subject "subject" on it. If client have valid certificate but having different "subject" then connection is still
|
||||
not allowed.
|
||||
|
||||
Example:
|
||||
@example
|
||||
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com"
|
||||
@end example
|
||||
|
||||
@item
|
||||
@code{REQUIRE CIPHER cipher} is needed to assure enough strong ciphers and keylengths to be used. SSL himself can be weak if old algorithms with short encryption keys are used. Using this option we can ask for some exact cipher to allow connection.
|
||||
|
||||
Example:
|
||||
@example
|
||||
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE CIPHER "EDH-RSA-DES-CBC3-SHA"
|
||||
@end example
|
||||
|
||||
Also it is allowed to combine those options with each other like this:
|
||||
@example
|
||||
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret"
|
||||
REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com"
|
||||
AND ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@@mysql.com"
|
||||
AND CIPHER "EDH-RSA-DES-CBC3-SHA"
|
||||
@end example
|
||||
|
||||
But it is not allowed to use any of options twice. Only different options can be mixed.
|
||||
@end itemize
|
||||
-----------
|
||||
|
||||
@node User names, Privilege changes, GRANT, User Account Management
|
||||
@subsection MySQL User Names and Passwords
|
||||
@ -19830,7 +19948,7 @@ differ somewhat:
|
||||
| have_bdb | YES |
|
||||
| have_innodb | YES |
|
||||
| have_raid | YES |
|
||||
| have_ssl | NO |
|
||||
| have_openssl | NO |
|
||||
| init_file | |
|
||||
| interactive_timeout | 28800 |
|
||||
| join_buffer_size | 131072 |
|
||||
@ -20017,7 +20135,7 @@ if @code{--skip-bdb} is used.
|
||||
if @code{--skip-innodb} is used.
|
||||
@item @code{have_raid}
|
||||
@code{YES} if @code{mysqld} supports the @code{RAID} option.
|
||||
@item @code{have_ssl}
|
||||
@item @code{have_openssl}
|
||||
@code{YES} if @code{mysqld} supports SSL (encryption) on the client/server
|
||||
protocol.
|
||||
|
||||
@ -21651,7 +21769,7 @@ mysql> show variables like "have_%";
|
||||
| have_innodb | NO |
|
||||
| have_isam | YES |
|
||||
| have_raid | NO |
|
||||
| have_ssl | NO |
|
||||
| have_openssl | NO |
|
||||
+---------------+-------+
|
||||
@end example
|
||||
|
||||
@ -48296,7 +48414,7 @@ Allow hex constants in the @code{--fields-*-by} and
|
||||
Added option @code{--safe-show-database} to @code{mysqld}.
|
||||
@item
|
||||
Added @code{have_bdb}, @code{have_gemini}, @code{have_innobase},
|
||||
@code{have_raid} and @code{have_ssl} to @code{SHOW VARIABLES} to make it
|
||||
@code{have_raid} and @code{have_openssl} to @code{SHOW VARIABLES} to make it
|
||||
easy to test for supported extensions.
|
||||
@item
|
||||
Added option @code{--open-files-limit} to @code{mysqld}.
|
||||
|
@ -663,7 +663,7 @@ if test "$cpu_vendor" = "AuthenticAMD"; then
|
||||
fi
|
||||
elif test "$cpu_vendor" = "GenuineIntel"; then
|
||||
if test $cpu_family>=6; then
|
||||
cpu_set=" pentiumpro pentium i486 i386";
|
||||
cpu_set="pentiumpro pentium i486 i386";
|
||||
elif test $cpu_family=5; then
|
||||
cpu_set="pentium i486 i386";
|
||||
elif test $cpu_family=4; then
|
||||
@ -682,9 +682,9 @@ done
|
||||
if test "$mysql_cv_cpu" = "unknown"
|
||||
then
|
||||
CFLAGS="$ac_save_CFLAGS"
|
||||
AC_MSG_RESULT(none)
|
||||
AC_MSG_RESULT(none)
|
||||
else
|
||||
AC_MSG_RESULT($mysql_cv_cpu)
|
||||
AC_MSG_RESULT($mysql_cv_cpu)
|
||||
fi
|
||||
]))
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
* Jani Tolonen <jani@mysql.com>
|
||||
* Matt Wagner <mwagner@mysql.com>
|
||||
* Jeremy Cole <jcole@mysql.com>
|
||||
* Tonu Samuel <tonu@mysql.com>
|
||||
*
|
||||
**/
|
||||
|
||||
@ -1232,6 +1233,7 @@ You can turn off this feature to get a quicker startup with -A\n\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
/* FIXME: free() on small chunks is sloooowwww. glibc bug */
|
||||
if (field_names) {
|
||||
for (i=0; field_names[i]; i++) {
|
||||
for (j=0; field_names[i][j]; j++) {
|
||||
@ -2219,7 +2221,7 @@ sql_real_connect(char *host,char *database,char *user,char *password,
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath);
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
#endif
|
||||
if (safe_updates)
|
||||
{
|
||||
|
@ -265,7 +265,7 @@ int main(int argc,char *argv[])
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath);
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
#endif /* HAVE_OPENSSL */
|
||||
if (sql_connect(&mysql,host,user,opt_password,option_wait))
|
||||
error = 1;
|
||||
|
@ -591,7 +591,7 @@ static int dbConnect(char *host, char *user, char *passwd)
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath);
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
#endif
|
||||
if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
|
||||
NULL, opt_mysql_port, opt_mysql_unix_port, 0)))
|
||||
|
@ -523,7 +523,7 @@ static int dbConnect(char *host, char *user,char *passwd)
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath);
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
#endif
|
||||
if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
|
||||
NULL,opt_mysql_port,opt_mysql_unix_port,
|
||||
|
@ -400,7 +400,7 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd)
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath);
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
#endif
|
||||
if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
|
||||
database,opt_mysql_port,opt_mysql_unix_port,
|
||||
|
@ -87,7 +87,7 @@ int main(int argc, char **argv)
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (opt_use_ssl)
|
||||
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
|
||||
opt_ssl_capath);
|
||||
opt_ssl_capath, opt_ssl_cipher);
|
||||
#endif
|
||||
if (!(mysql_real_connect(&mysql,host,user,opt_password,
|
||||
argv[0],opt_mysql_port,opt_mysql_unix_port,
|
||||
|
@ -135,6 +135,7 @@ struct st_mysql_options {
|
||||
char *ssl_cert; /* PEM cert file */
|
||||
char *ssl_ca; /* PEM CA file */
|
||||
char *ssl_capath; /* PEM directory of CA-s? */
|
||||
char *ssl_cipher; /* cipher to use */
|
||||
my_bool use_ssl; /* if to use SSL or not */
|
||||
my_bool compress,named_pipe;
|
||||
/*
|
||||
@ -262,7 +263,7 @@ const char * STDCALL mysql_character_set_name(MYSQL *mysql);
|
||||
MYSQL * STDCALL mysql_init(MYSQL *mysql);
|
||||
int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
|
||||
const char *cert, const char *ca,
|
||||
const char *capath);
|
||||
const char *capath, const char *cipher);
|
||||
int STDCALL mysql_ssl_clear(MYSQL *mysql);
|
||||
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
|
||||
const char *passwd, const char *db);
|
||||
|
@ -221,4 +221,7 @@
|
||||
#define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1218
|
||||
#define ER_CANT_UPDATE_WITH_READLOCK 1219
|
||||
#define ER_MIXING_NOT_ALLOWED 1220
|
||||
#define ER_ERROR_MESSAGES 221
|
||||
#define ER_GRANT_DUPL_SUBJECT 1221
|
||||
#define ER_GRANT_DUPL_ISSUER 1222
|
||||
#define ER_GRANT_DUPL_CIPHER 1223
|
||||
#define ER_ERROR_MESSAGES 224
|
||||
|
@ -39,4 +39,10 @@
|
||||
my_free(opt_ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
|
||||
opt_ssl_ca = my_strdup(optarg, MYF(0));
|
||||
break;
|
||||
case OPT_SSL_CIPHER:
|
||||
opt_use_ssl = 1; /* true */
|
||||
my_free(opt_ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
|
||||
opt_ssl_cipher = my_strdup(optarg, MYF(0));
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
@ -22,10 +22,12 @@
|
||||
#define OPT_SSL_CERT 202
|
||||
#define OPT_SSL_CA 203
|
||||
#define OPT_SSL_CAPATH 204
|
||||
#define OPT_SSL_CIPHER 205
|
||||
{"ssl", no_argument, 0, OPT_SSL_SSL},
|
||||
{"ssl-key", required_argument, 0, OPT_SSL_KEY},
|
||||
{"ssl-cert", required_argument, 0, OPT_SSL_CERT},
|
||||
{"ssl-ca", required_argument, 0, OPT_SSL_CA},
|
||||
{"ssl-capath", required_argument, 0, OPT_SSL_CAPATH},
|
||||
{"ssl-cipher", required_argument, 0, OPT_SSL_CIPHER},
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
@ -21,5 +21,6 @@
|
||||
--ssl-key X509 key in PEM format (implies --ssl)\n\
|
||||
--ssl-cert X509 cert in PEM format (implies --ssl)\n\
|
||||
--ssl-ca CA file in PEM format (check OpenSSL docs, implies --ssl)\n\
|
||||
--ssl-capath CA directory (check OpenSSL docs, implies --ssl)");
|
||||
--ssl-capath CA directory (check OpenSSL docs, implies --ssl)\n\
|
||||
--ssl-cipher SSL cipher to use (implies --ssl)");
|
||||
#endif
|
||||
|
@ -21,4 +21,5 @@ static char *opt_ssl_key = 0;
|
||||
static char *opt_ssl_cert = 0;
|
||||
static char *opt_ssl_ca = 0;
|
||||
static char *opt_ssl_capath = 0;
|
||||
static char *opt_ssl_cipher = 0;
|
||||
#endif
|
||||
|
@ -169,9 +169,6 @@ struct st_VioSSLAcceptorFd
|
||||
state_connect = 1,
|
||||
state_accept = 2
|
||||
};
|
||||
// BIO* bio_;
|
||||
// char desc_[100];
|
||||
// Vio* sd_;
|
||||
|
||||
/* function pointers which are only once for SSL server
|
||||
Vio*(*sslaccept)(struct st_VioSSLAcceptorFd*,Vio*); */
|
||||
@ -184,15 +181,17 @@ struct st_VioSSLConnectorFd
|
||||
SSL_METHOD* ssl_method_;
|
||||
/* function pointers which are only once for SSL client */
|
||||
};
|
||||
void sslaccept(struct st_VioSSLAcceptorFd*, Vio*);
|
||||
void sslconnect(struct st_VioSSLConnectorFd*, Vio*);
|
||||
void sslaccept(struct st_VioSSLAcceptorFd*, Vio*, long timeout);
|
||||
void sslconnect(struct st_VioSSLConnectorFd*, Vio*, long timeout);
|
||||
|
||||
struct st_VioSSLConnectorFd
|
||||
*new_VioSSLConnectorFd(const char* key_file, const char* cert_file,
|
||||
const char* ca_file, const char* ca_path);
|
||||
const char* ca_file, const char* ca_path,
|
||||
const char* cipher);
|
||||
struct st_VioSSLAcceptorFd
|
||||
*new_VioSSLAcceptorFd(const char* key_file, const char* cert_file,
|
||||
const char* ca_file,const char* ca_path);
|
||||
const char* ca_file,const char* ca_path,
|
||||
const char* cipher);
|
||||
Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state);
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -200,6 +199,9 @@ Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state);
|
||||
#endif
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
/* This enumerator is used in parser - should be always visible */
|
||||
enum SSL_type {SSL_TYPE_NONE, SSL_TYPE_ANY, SSL_TYPE_X509, SSL_TYPE_SPECIFIED};
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
/* This structure is for every connection on both sides */
|
||||
struct st_vio
|
||||
@ -229,10 +231,8 @@ struct st_vio
|
||||
my_bool (*poll_read)(Vio*,uint);
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
BIO* bio_;
|
||||
SSL* ssl_;
|
||||
my_bool open_;
|
||||
char *ssl_cip_;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
#endif /* HAVE_VIO */
|
||||
};
|
||||
|
@ -695,7 +695,7 @@ mysql_free_result(MYSQL_RES *result)
|
||||
static const char *default_options[]=
|
||||
{"port","socket","compress","password","pipe", "timeout", "user",
|
||||
"init-command", "host", "database", "debug", "return-found-rows",
|
||||
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath",
|
||||
"ssl-key" ,"ssl-cert" ,"ssl-ca" ,"ssl-capath", "ssl-cipher"
|
||||
"character-set-dir", "default-character-set", "interactive-timeout",
|
||||
"connect_timeout", "replication-probe", "enable-reads-from-master",
|
||||
"repl-parse-query",
|
||||
@ -1368,15 +1368,17 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
|
||||
const char *key __attribute__((unused)),
|
||||
const char *cert __attribute__((unused)),
|
||||
const char *ca __attribute__((unused)),
|
||||
const char *capath __attribute__((unused)))
|
||||
const char *capath __attribute__((unused)),
|
||||
const char *cipher __attribute__((unused)))
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
mysql->options.ssl_key = key==0 ? 0 : my_strdup(key,MYF(0));
|
||||
mysql->options.ssl_cert = cert==0 ? 0 : my_strdup(cert,MYF(0));
|
||||
mysql->options.ssl_ca = ca==0 ? 0 : my_strdup(ca,MYF(0));
|
||||
mysql->options.ssl_capath = capath==0 ? 0 : my_strdup(capath,MYF(0));
|
||||
mysql->options.ssl_cipher = cipher==0 ? 0 : my_strdup(cipher,MYF(0));
|
||||
mysql->options.use_ssl = TRUE;
|
||||
mysql->connector_fd = (gptr)new_VioSSLConnectorFd(key, cert, ca, capath);
|
||||
mysql->connector_fd = (gptr)new_VioSSLConnectorFd(key, cert, ca, capath, cipher);
|
||||
DBUG_PRINT("info",("mysql_ssl_set, context: %p",((struct st_VioSSLConnectorFd *)(mysql->connector_fd))->ssl_context_));
|
||||
#endif
|
||||
return 0;
|
||||
@ -1396,10 +1398,12 @@ mysql_ssl_clear(MYSQL *mysql __attribute__((unused)))
|
||||
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));
|
||||
mysql->options.ssl_key = 0;
|
||||
mysql->options.ssl_cert = 0;
|
||||
mysql->options.ssl_ca = 0;
|
||||
mysql->options.ssl_capath = 0;
|
||||
mysql->options.ssl_cipher= 0;
|
||||
mysql->options.use_ssl = FALSE;
|
||||
my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
|
||||
mysql->connector_fd = 0;
|
||||
@ -1797,7 +1801,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
||||
/* Do the SSL layering. */
|
||||
DBUG_PRINT("info", ("IO layer change in progress..."));
|
||||
DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_));
|
||||
sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio);
|
||||
sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio, (long)(mysql->options.connect_timeout));
|
||||
DBUG_PRINT("info", ("IO layer change done!"));
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
@ -1887,7 +1891,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
|
||||
if (!mysql->reconnect ||
|
||||
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info)
|
||||
{
|
||||
/* Allov reconnect next time */
|
||||
/* Allow reconnect next time */
|
||||
mysql->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
@ -1995,13 +1999,13 @@ mysql_close(MYSQL *mysql)
|
||||
my_free(mysql->options.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(mysql->options.charset_dir,MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(mysql->options.charset_name,MYF(MY_ALLOW_ZERO_PTR));
|
||||
#ifdef HAVE_OPENSSL
|
||||
mysql_ssl_clear(mysql);
|
||||
#endif /* HAVE_OPENSSL */
|
||||
/* Clear pointers for better safety */
|
||||
mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
|
||||
bzero((char*) &mysql->options,sizeof(mysql->options));
|
||||
mysql->net.vio = 0;
|
||||
#ifdef HAVE_OPENSSL
|
||||
mysql_ssl_clear(mysql);
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
/* free/close slave list */
|
||||
if (mysql->rpl_pivot)
|
||||
|
@ -257,7 +257,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
|
||||
send_error(net,ER_OUT_OF_RESOURCES);
|
||||
return 1;
|
||||
}
|
||||
thd->master_access=acl_getroot(thd->host, thd->ip, thd->user,
|
||||
thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user,
|
||||
passwd, thd->scramble, &thd->priv_user,
|
||||
protocol_version == 9 ||
|
||||
!(thd->client_capabilities &
|
||||
|
@ -134,7 +134,7 @@ then
|
||||
c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
|
||||
c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
|
||||
c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
|
||||
c_u="$c_u ssl_type enum('none', 'cipher', 'x509','issuer','subject') NOT NULL,"
|
||||
c_u="$c_u ssl_type enum('NONE','ANY', 'X509', 'SPECIFIED') NOT NULL,"
|
||||
c_u="$c_u ssl_cipher char(60) NULL,"
|
||||
c_u="$c_u x509_issuer blob NULL,"
|
||||
c_u="$c_u x509_subject blob NULL,"
|
||||
|
@ -224,18 +224,22 @@ then
|
||||
c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
|
||||
c_u="$c_u Index_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
|
||||
c_u="$c_u Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL,"
|
||||
c_u="$c_u ssl_type enum('NONE','ANY','X509', 'SPECIFIED') DEFAULT 'NONE' NOT NULL,"
|
||||
c_u="$c_u ssl_cipher BLOB NULL,"
|
||||
c_u="$c_u x509_issuer BLOB NULL,"
|
||||
c_u="$c_u x509_subject BLOB NULL,"
|
||||
c_u="$c_u PRIMARY KEY Host (Host,User)"
|
||||
c_u="$c_u )"
|
||||
c_u="$c_u comment='Users and global privileges';"
|
||||
|
||||
i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
|
||||
INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
|
||||
i_u="INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE',NULL,NULL,NULL);
|
||||
INSERT INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE',NULL,NULL,NULL);
|
||||
|
||||
REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
|
||||
REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
|
||||
REPLACE INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE',NULL,NULL,NULL);
|
||||
REPLACE INTO user VALUES ('$hostname','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','NONE',NULL,NULL,NULL);
|
||||
|
||||
INSERT INTO user VALUES ('localhost','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');
|
||||
INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N');"
|
||||
INSERT INTO user VALUES ('localhost','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','NONE',NULL,NULL,NULL);
|
||||
INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','NONE',NULL,NULL,NULL);"
|
||||
fi
|
||||
|
||||
if test ! -f $mdata/func.frm
|
||||
|
@ -319,6 +319,7 @@ static SYMBOL symbols[] = {
|
||||
{ "SQL_SLAVE_SKIP_COUNTER", SYM(SQL_SLAVE_SKIP_COUNTER),0,0},
|
||||
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0},
|
||||
{ "SQL_WARNINGS", SYM(SQL_WARNINGS),0,0},
|
||||
{ "SSL", SYM(SSL_SYM),0,0},
|
||||
{ "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0},
|
||||
{ "START", SYM(START_SYM),0,0},
|
||||
{ "STARTING", SYM(STARTING),0,0},
|
||||
@ -362,6 +363,7 @@ static SYMBOL symbols[] = {
|
||||
{ "WRITE", SYM(WRITE_SYM),0,0},
|
||||
{ "WHEN", SYM(WHEN_SYM),0,0},
|
||||
{ "WHERE", SYM(WHERE),0,0},
|
||||
{ "X509", SYM(X509_SYM),0,0},
|
||||
{ "YEAR", SYM(YEAR_SYM),0,0},
|
||||
{ "YEAR_MONTH", SYM(YEAR_MONTH_SYM),0,0},
|
||||
{ "ZEROFILL", SYM(ZEROFILL),0,0},
|
||||
|
@ -803,7 +803,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
|
||||
/* Do the SSL layering. */
|
||||
DBUG_PRINT("info", ("IO layer change in progress..."));
|
||||
DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_));
|
||||
sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio);
|
||||
sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio,60L);
|
||||
DBUG_PRINT("info", ("IO layer change done!"));
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
@ -242,16 +242,11 @@ static char **defaults_argv,time_zone[30];
|
||||
static const char *default_table_type_name;
|
||||
static char glob_hostname[FN_REFLEN];
|
||||
|
||||
#include "sslopt-vars.h"
|
||||
#ifdef HAVE_OPENSSL
|
||||
static bool opt_use_ssl = FALSE;
|
||||
static char *opt_ssl_key = 0;
|
||||
static char *opt_ssl_cert = 0;
|
||||
static char *opt_ssl_ca = 0;
|
||||
static char *opt_ssl_capath = 0;
|
||||
struct st_VioSSLAcceptorFd * ssl_acceptor_fd = 0;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
||||
|
||||
I_List <i_string_pair> replicate_rewrite_db;
|
||||
I_List<i_string> replicate_do_db, replicate_ignore_db;
|
||||
// allow the user to tell us which db to replicate and which to ignore
|
||||
@ -725,6 +720,7 @@ void clean_up(bool print_message)
|
||||
my_free(opt_ssl_cert,MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(opt_ssl_ca,MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(opt_ssl_capath,MYF(MY_ALLOW_ZERO_PTR));
|
||||
my_free(opt_ssl_cipher,MYF(MY_ALLOW_ZERO_PTR));
|
||||
opt_ssl_key=opt_ssl_cert=opt_ssl_ca=opt_ssl_capath=0;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
free_defaults(defaults_argv);
|
||||
@ -1712,7 +1708,7 @@ int main(int argc, char **argv)
|
||||
if (opt_use_ssl)
|
||||
{
|
||||
ssl_acceptor_fd = new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
|
||||
opt_ssl_ca, opt_ssl_capath);
|
||||
opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher);
|
||||
DBUG_PRINT("info",("ssl_acceptor_fd: %p",ssl_acceptor_fd));
|
||||
if (!ssl_acceptor_fd)
|
||||
opt_use_ssl=0;
|
||||
@ -3110,21 +3106,29 @@ struct show_var_st status_vars[]= {
|
||||
{"Sort_rows", (char*) &filesort_rows, SHOW_LONG},
|
||||
{"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG},
|
||||
#ifdef HAVE_OPENSSL
|
||||
{"SSL_CTX_sess_accept", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT},
|
||||
{"SSL_CTX_sess_accept_good", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD},
|
||||
{"SSL_CTX_sess_accept_renegotiate", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE},
|
||||
{"SSL_CTX_sess_cb_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS},
|
||||
{"SSL_CTX_sess_number", (char*) 0, SHOW_SSL_CTX_SESS_NUMBER},
|
||||
{"SSL_CTX_get_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE},
|
||||
{"SSL_CTX_sess_get_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE},
|
||||
{"SSL_CTX_get_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE},
|
||||
{"SSL_CTX_get_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH},
|
||||
{"SSL_get_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE},
|
||||
{"SSL_get_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH},
|
||||
{"SSL_session_reused", (char*) 0, SHOW_SSL_SESSION_REUSED},
|
||||
{"SSL_get_version", (char*) 0, SHOW_SSL_GET_VERSION},
|
||||
{"SSL_get_cipher", (char*) 0, SHOW_SSL_GET_CIPHER},
|
||||
{"SSL_get_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT},
|
||||
{"ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT},
|
||||
{"ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD},
|
||||
{"ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD},
|
||||
{"ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE},
|
||||
{"ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE},
|
||||
{"ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS},
|
||||
{"ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS},
|
||||
{"ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES},
|
||||
{"ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS},
|
||||
{"ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER},
|
||||
{"ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT},
|
||||
{"ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL},
|
||||
{"ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE},
|
||||
{"ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE},
|
||||
{"ssl_sessions_reused", (char*) 0, SHOW_SSL_SESSION_REUSED},
|
||||
{"ssl_ctx_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE},
|
||||
{"ssl_ctx_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH},
|
||||
{"ssl_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE},
|
||||
{"ssl_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH},
|
||||
{"ssl_version", (char*) 0, SHOW_SSL_GET_VERSION},
|
||||
{"ssl_cipher", (char*) 0, SHOW_SSL_GET_CIPHER},
|
||||
{"ssl_cipher_list", (char*) 0, SHOW_SSL_GET_CIPHER_LIST},
|
||||
{"ssl_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT},
|
||||
#endif /* HAVE_OPENSSL */
|
||||
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
|
||||
{"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
|
||||
|
@ -231,3 +231,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -225,3 +225,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -228,3 +228,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -222,3 +222,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -226,3 +226,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -222,3 +222,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -225,3 +225,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -222,3 +222,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -224,3 +224,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -222,3 +222,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -224,3 +224,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -222,3 +222,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -224,3 +224,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -224,3 +224,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -226,3 +226,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -222,3 +222,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -226,3 +226,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -225,3 +225,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -230,3 +230,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -223,3 +223,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -222,3 +222,6 @@
|
||||
"SELECT kommandona har olika antal kolumner"
|
||||
"Kan inte utföra kommandot emedan du har ett READ lås",
|
||||
"Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
@ -227,3 +227,6 @@
|
||||
"The used SELECT statements have a different number of columns",
|
||||
"Can't execute the query because you have a conflicting read lock",
|
||||
"Mixing of transactional and non-transactional tables is disabled",
|
||||
"Duplicate SUBJECT option in GRANT clause",
|
||||
"Duplicate ISSUER option in GRANT clause",
|
||||
"Duplicate CIPHER option in GRANT clause",
|
||||
|
258
sql/sql_acl.cc
258
sql/sql_acl.cc
@ -62,8 +62,9 @@ public:
|
||||
char *user,*password;
|
||||
ulong salt[2];
|
||||
#ifdef HAVE_OPENSSL
|
||||
char *ssl_type, *ssl_cipher, *x509_issuer, *x509_subject;
|
||||
#endif
|
||||
enum SSL_type ssl_type;
|
||||
const char *ssl_cipher, *x509_issuer, *x509_subject;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
};
|
||||
|
||||
class ACL_DB :public ACL_ACCESS
|
||||
@ -204,13 +205,19 @@ int acl_init(bool dont_read_acl_tables)
|
||||
user.password=get_field(&mem, table,2);
|
||||
#ifdef HAVE_OPENSSL
|
||||
DBUG_PRINT("info",("table->fields=%d",table->fields));
|
||||
if (table->fields >= 21) {
|
||||
user.ssl_type=get_field(&mem, table,17);
|
||||
if (table->fields >= 21) { /* From 4.0.0 we have more fields */
|
||||
if(!strcmp(get_field(&mem, table,17),"ANY"))
|
||||
user.ssl_type=SSL_TYPE_ANY;
|
||||
else if(!strcmp(get_field(&mem, table,17),"X509"))
|
||||
user.ssl_type=SSL_TYPE_X509;
|
||||
else if(!strcmp(get_field(&mem, table,17),"SPECIFIED"))
|
||||
user.ssl_type=SSL_TYPE_SPECIFIED;
|
||||
else user.ssl_type=SSL_TYPE_NONE;
|
||||
user.ssl_cipher=get_field(&mem, table,18);
|
||||
user.x509_issuer=get_field(&mem, table,19);
|
||||
user.x509_subject=get_field(&mem, table,20);
|
||||
}
|
||||
#endif
|
||||
#endif /* HAVE_OPENSSL */
|
||||
if (user.password && (length=(uint) strlen(user.password)) == 8 &&
|
||||
protocol_version == PROTOCOL_VERSION)
|
||||
{
|
||||
@ -410,15 +417,14 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b)
|
||||
}
|
||||
|
||||
|
||||
/* Get master privilges for user (priviliges for all tables) */
|
||||
|
||||
|
||||
uint acl_getroot(const char *host, const char *ip, const char *user,
|
||||
/* Get master privilges for user (priviliges for all tables). Required to connect */
|
||||
uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
||||
const char *password,const char *message,char **priv_user,
|
||||
bool old_ver)
|
||||
{
|
||||
uint user_access=NO_ACCESS;
|
||||
*priv_user=(char*) user;
|
||||
char *ptr=0;
|
||||
|
||||
if (!initialized)
|
||||
return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */
|
||||
@ -440,7 +446,88 @@ uint acl_getroot(const char *host, const char *ip, const char *user,
|
||||
!check_scramble(password,message,acl_user->salt,
|
||||
(my_bool) old_ver)))
|
||||
{
|
||||
#ifdef HAVE_OPENSSL
|
||||
#define vio (thd->net.vio)
|
||||
/* In this point we know that user is allowed to connect
|
||||
* from given host by given username/password pair. Now
|
||||
* we check if SSL is required, if user is using SSL and
|
||||
* if X509 certificate attributes are OK
|
||||
*/
|
||||
switch(acl_user->ssl_type) {
|
||||
case SSL_TYPE_NONE: /* SSL is not required to connect */
|
||||
user_access=acl_user->access;
|
||||
break;
|
||||
case SSL_TYPE_ANY: /* Any kind of SSL is good enough */
|
||||
if(vio_type(vio) == VIO_TYPE_SSL)
|
||||
user_access=acl_user->access;
|
||||
break;
|
||||
case SSL_TYPE_X509: /* Client should have any valid certificate. */
|
||||
/* Connections with non-valid certificates are dropped already
|
||||
* in sslaccept() anyway, so we do not check validity here.
|
||||
*/
|
||||
if(SSL_get_peer_certificate(vio->ssl_))
|
||||
user_access=acl_user->access;
|
||||
break;
|
||||
case SSL_TYPE_SPECIFIED: /* Client should have attributes as specified */
|
||||
/* We do not check for absence of SSL because without SSL it does not
|
||||
* pass all checks here anyway.
|
||||
*/
|
||||
/* If cipher name is specified, we compare it to actual cipher in use */
|
||||
if(acl_user->ssl_cipher)
|
||||
DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'",
|
||||
acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_)));
|
||||
if(!strcmp(acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_)))
|
||||
user_access=acl_user->access;
|
||||
else
|
||||
{
|
||||
user_access=NO_ACCESS;
|
||||
break;
|
||||
}
|
||||
/* Prepare certificate (if exists) */
|
||||
DBUG_PRINT("info",("checkpoint 1"));
|
||||
X509* cert=SSL_get_peer_certificate(vio->ssl_);
|
||||
DBUG_PRINT("info",("checkpoint 2"));
|
||||
/* If X509 issuer is speified, we check it... */
|
||||
if(acl_user->x509_issuer)
|
||||
{
|
||||
DBUG_PRINT("info",("checkpoint 3"));
|
||||
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))
|
||||
user_access=acl_user->access;
|
||||
else
|
||||
{
|
||||
user_access=NO_ACCESS;
|
||||
free(ptr);
|
||||
break;
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
DBUG_PRINT("info",("checkpoint 4"));
|
||||
/* X509 subject is specified, we check it .. */
|
||||
if(acl_user->x509_subject)
|
||||
{
|
||||
ptr = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
|
||||
DBUG_PRINT("info",("comparing subjects: '%s' and '%s'",
|
||||
acl_user->x509_subject, ptr));
|
||||
if(!strcmp(acl_user->x509_subject,ptr))
|
||||
user_access=acl_user->access;
|
||||
else
|
||||
{
|
||||
user_access=NO_ACCESS;
|
||||
free(ptr);
|
||||
break;
|
||||
}
|
||||
free(ptr);
|
||||
}
|
||||
DBUG_PRINT("info",("checkpoint 5"));
|
||||
break;
|
||||
}
|
||||
DBUG_PRINT("info",("checkpoint 6"));
|
||||
#else /* HAVE_OPENSSL */
|
||||
user_access=acl_user->access;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
if (!acl_user->user)
|
||||
*priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */
|
||||
break;
|
||||
@ -469,7 +556,14 @@ static byte* check_get_key(ACL_USER *buff,uint *length,
|
||||
}
|
||||
|
||||
static void acl_update_user(const char *user, const char *host,
|
||||
const char *password, uint privileges)
|
||||
const char *password,
|
||||
#ifdef HAVE_OPENSSL
|
||||
enum SSL_type ssl_type,
|
||||
const char *ssl_cipher,
|
||||
const char *x509_issuer,
|
||||
const char *x509_subject,
|
||||
#endif /* HAVE_OPENSSL */
|
||||
uint privileges)
|
||||
{
|
||||
for (uint i=0 ; i < acl_users.elements ; i++)
|
||||
{
|
||||
@ -482,6 +576,12 @@ static void acl_update_user(const char *user, const char *host,
|
||||
acl_user->host.hostname && !strcmp(host,acl_user->host.hostname))
|
||||
{
|
||||
acl_user->access=privileges;
|
||||
#ifdef HAVE_OPENSSL
|
||||
acl_user->ssl_type=ssl_type;
|
||||
acl_user->ssl_cipher=ssl_cipher;
|
||||
acl_user->x509_issuer=x509_issuer;
|
||||
acl_user->x509_subject=x509_subject;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
if (password)
|
||||
{
|
||||
if (!password[0])
|
||||
@ -500,7 +600,13 @@ static void acl_update_user(const char *user, const char *host,
|
||||
|
||||
|
||||
static void acl_insert_user(const char *user, const char *host,
|
||||
const char *password,
|
||||
const char *password,
|
||||
#ifdef HAVE_OPENSSL
|
||||
enum SSL_type ssl_type,
|
||||
const char *ssl_cipher,
|
||||
const char *x509_issuer,
|
||||
const char *x509_subject,
|
||||
#endif /* HAVE_OPENSSL */
|
||||
uint privileges)
|
||||
{
|
||||
ACL_USER acl_user;
|
||||
@ -510,6 +616,12 @@ static void acl_insert_user(const char *user, const char *host,
|
||||
acl_user.access=privileges;
|
||||
acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user);
|
||||
acl_user.hostname_length=(uint) strlen(acl_user.host.hostname);
|
||||
#ifdef HAVE_OPENSSL
|
||||
acl_user.ssl_type=ssl_type;
|
||||
acl_user.ssl_cipher=ssl_cipher;
|
||||
acl_user.x509_issuer=x509_issuer;
|
||||
acl_user.x509_subject=x509_subject;
|
||||
#endif /* HAVE_OPENSSL */
|
||||
if (password)
|
||||
{
|
||||
acl_user.password=(char*) ""; // Just point at something
|
||||
@ -984,7 +1096,7 @@ static bool test_if_create_new_users(THD *thd)
|
||||
** Handle GRANT commands
|
||||
****************************************************************************/
|
||||
|
||||
static int replace_user_table(TABLE *table, const LEX_USER &combo,
|
||||
static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
|
||||
uint rights, char what, bool create_user)
|
||||
{
|
||||
int error = -1;
|
||||
@ -1044,7 +1156,40 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
|
||||
table->field[i]->store(&what,1);
|
||||
}
|
||||
rights=get_access(table,3);
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
/* We write down SSL related ACL stuff */
|
||||
DBUG_PRINT("info",("table->fields=%d",table->fields));
|
||||
if (table->fields >= 21) { /* From 4.0.0 we have more fields */
|
||||
switch (thd->lex.ssl_type) {
|
||||
case SSL_TYPE_ANY:
|
||||
table->field[17]->store("ANY",3);
|
||||
table->field[18]->store("",0);
|
||||
table->field[19]->store("",0);
|
||||
table->field[20]->store("",0);
|
||||
break;
|
||||
case SSL_TYPE_X509:
|
||||
table->field[17]->store("X509",4);
|
||||
table->field[18]->store("",0);
|
||||
table->field[19]->store("",0);
|
||||
table->field[20]->store("",0);
|
||||
break;
|
||||
case SSL_TYPE_SPECIFIED:
|
||||
table->field[17]->store("SPECIFIED",9);
|
||||
if(thd->lex.ssl_cipher)
|
||||
table->field[18]->store(thd->lex.ssl_cipher,strlen(thd->lex.ssl_cipher));
|
||||
if(thd->lex.x509_issuer)
|
||||
table->field[19]->store(thd->lex.x509_issuer,strlen(thd->lex.x509_issuer));
|
||||
if(thd->lex.x509_subject)
|
||||
table->field[20]->store(thd->lex.x509_subject,strlen(thd->lex.x509_subject));
|
||||
break;
|
||||
default:
|
||||
table->field[17]->store("NONE",4);
|
||||
table->field[18]->store("",0);
|
||||
table->field[19]->store("",0);
|
||||
table->field[20]->store("",0);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
if (old_row_exists)
|
||||
{
|
||||
/*
|
||||
@ -1078,9 +1223,23 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
|
||||
if (!combo.password.str)
|
||||
password=0; // No password given on command
|
||||
if (old_row_exists)
|
||||
acl_update_user(combo.user.str,combo.host.str,password,rights);
|
||||
acl_update_user(combo.user.str,combo.host.str,password,
|
||||
#ifdef HAVE_OPENSSL
|
||||
thd->lex.ssl_type,
|
||||
thd->lex.ssl_cipher,
|
||||
thd->lex.x509_issuer,
|
||||
thd->lex.x509_subject,
|
||||
#endif /* HAVE_OPENSSL */
|
||||
rights);
|
||||
else
|
||||
acl_insert_user(combo.user.str,combo.host.str,password,rights);
|
||||
acl_insert_user(combo.user.str,combo.host.str,password,
|
||||
#ifdef HAVE_OPENSSL
|
||||
thd->lex.ssl_type,
|
||||
thd->lex.ssl_cipher,
|
||||
thd->lex.x509_issuer,
|
||||
thd->lex.x509_subject,
|
||||
#endif /* HAVE_OPENSSL */
|
||||
rights);
|
||||
}
|
||||
table->file->index_end();
|
||||
DBUG_RETURN(error);
|
||||
@ -1626,6 +1785,9 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
|
||||
TABLE_LIST tables[3];
|
||||
bool create_new_users=0;
|
||||
DBUG_ENTER("mysql_table_grant");
|
||||
DBUG_PRINT("info",("ssl_cipher=%s",thd->lex.ssl_cipher));
|
||||
DBUG_PRINT("info",("x509_issuer=%s",thd->lex.x509_issuer));
|
||||
DBUG_PRINT("info",("x509_subject=%s",thd->lex.x509_subject));
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
@ -1715,9 +1877,10 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
|
||||
continue;
|
||||
}
|
||||
/* Create user if needed */
|
||||
if (replace_user_table(tables[0].table,
|
||||
*Str,
|
||||
0,
|
||||
if (replace_user_table(thd,
|
||||
tables[0].table,
|
||||
*Str,
|
||||
0,
|
||||
revoke_grant ? 'N' : 'Y',
|
||||
create_new_users))
|
||||
{
|
||||
@ -1810,7 +1973,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
|
||||
pthread_mutex_unlock(&LOCK_grant);
|
||||
if (!result)
|
||||
send_ok(&thd->net);
|
||||
/* Tables are automaticly closed */
|
||||
/* Tables are automatically closed */
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
@ -1871,7 +2034,8 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
|
||||
result= -1;
|
||||
continue;
|
||||
}
|
||||
if ((replace_user_table(tables[0].table,
|
||||
if ((replace_user_table(thd,
|
||||
tables[0].table,
|
||||
*Str,
|
||||
(!db ? rights : 0), what, create_new_users)))
|
||||
result= -1;
|
||||
@ -2332,6 +2496,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
{
|
||||
uint counter, want_access,index;
|
||||
int error = 0;
|
||||
int ssl_options = 0;
|
||||
ACL_USER *acl_user; ACL_DB *acl_db;
|
||||
char buff[1024];
|
||||
DBUG_ENTER("mysql_show_grants");
|
||||
@ -2426,30 +2591,37 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
|
||||
global.append('\'');
|
||||
}
|
||||
#ifdef HAVE_OPENSSL
|
||||
/* SSL grant stuff */
|
||||
DBUG_PRINT("info",("acl_user->ssl_type=%s",acl_user->ssl_type));
|
||||
DBUG_PRINT("info",("acl_user->ssl_cipher=%s",acl_user->ssl_cipher));
|
||||
DBUG_PRINT("info",("acl_user->x509_subject=%s",acl_user->x509_subject));
|
||||
DBUG_PRINT("info",("acl_user->x509_issuer=%s",acl_user->x509_issuer));
|
||||
if(acl_user->ssl_type) {
|
||||
if(!strcmp(acl_user->ssl_type,"ssl"))
|
||||
global.append(" REQUIRE SSL",12);
|
||||
else if(!strcmp(acl_user->ssl_type,"x509"))
|
||||
{
|
||||
global.append(" REQUIRE X509 ",14);
|
||||
if(acl_user->x509_issuer) {
|
||||
global.append("SUBJECT \"",9);
|
||||
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
|
||||
global.append("\"",1);
|
||||
}
|
||||
if(acl_user->x509_subject) {
|
||||
global.append("ISSUER \"",8);
|
||||
global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
|
||||
global.append("\"",1);
|
||||
}
|
||||
}
|
||||
/* "show grants" SSL related stuff */
|
||||
if(acl_user->ssl_type==SSL_TYPE_ANY)
|
||||
global.append(" REQUIRE SSL",12);
|
||||
else if(acl_user->ssl_type==SSL_TYPE_X509)
|
||||
global.append(" REQUIRE X509",13);
|
||||
else if(acl_user->ssl_type==SSL_TYPE_SPECIFIED)
|
||||
{
|
||||
global.append(" REQUIRE ",9);
|
||||
if(acl_user->x509_issuer) {
|
||||
if(ssl_options++)
|
||||
global.append(" AND ",5);
|
||||
global.append("ISSUER \"",8);
|
||||
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
|
||||
global.append("\"",1);
|
||||
}
|
||||
#endif
|
||||
if(acl_user->x509_subject) {
|
||||
if(ssl_options++)
|
||||
global.append(" AND ",5);
|
||||
global.append("SUBJECT \"",9);
|
||||
global.append(acl_user->x509_subject,strlen(acl_user->x509_subject));
|
||||
global.append("\"",1);
|
||||
}
|
||||
if(acl_user->ssl_cipher) {
|
||||
if(ssl_options++)
|
||||
global.append(" AND ",5);
|
||||
global.append("CIPHER \"",8);
|
||||
global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher));
|
||||
global.append("\"",1);
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_OPENSSL */
|
||||
if (want_access & GRANT_ACL)
|
||||
global.append(" WITH GRANT OPTION",18);
|
||||
thd->packet.length(0);
|
||||
|
@ -59,7 +59,7 @@ void acl_reload(void);
|
||||
void acl_free(bool end=0);
|
||||
uint acl_get(const char *host, const char *ip, const char *bin_ip,
|
||||
const char *user, const char *db);
|
||||
uint acl_getroot(const char *host, const char *ip, const char *user,
|
||||
uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user,
|
||||
const char *password,const char *scramble,char **priv_user,
|
||||
bool old_ver);
|
||||
bool acl_check_host(const char *host, const char *ip);
|
||||
|
@ -56,7 +56,7 @@ enum enum_sql_command {
|
||||
SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA,
|
||||
SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
|
||||
SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_MULTI_DELETE,
|
||||
SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER,
|
||||
SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER
|
||||
};
|
||||
|
||||
enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
|
||||
@ -145,7 +145,8 @@ typedef struct st_lex {
|
||||
char *length,*dec,*change,*name;
|
||||
char *backup_dir; /* For RESTORE/BACKUP */
|
||||
char* to_log; /* For PURGE MASTER LOGS TO */
|
||||
char* ssl_subject,*ssl_issuer,*ssl_chipher;
|
||||
char* x509_subject,*x509_issuer,*ssl_cipher;
|
||||
enum SSL_type ssl_type; /* defined in violite.h */
|
||||
String *wild;
|
||||
sql_exchange *exchange;
|
||||
|
||||
|
@ -115,7 +115,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
|
||||
send_error(net,ER_OUT_OF_RESOURCES);
|
||||
return 1;
|
||||
}
|
||||
thd->master_access=acl_getroot(thd->host, thd->ip, thd->user,
|
||||
thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user,
|
||||
passwd, thd->scramble, &thd->priv_user,
|
||||
protocol_version == 9 ||
|
||||
!(thd->client_capabilities &
|
||||
@ -433,7 +433,7 @@ check_connections(THD *thd)
|
||||
DBUG_PRINT("info", ("Agreed to change IO layer to SSL") );
|
||||
/* Do the SSL layering. */
|
||||
DBUG_PRINT("info", ("IO layer change in progress..."));
|
||||
sslaccept(ssl_acceptor_fd, net->vio);
|
||||
sslaccept(ssl_acceptor_fd, net->vio, (long)60L);
|
||||
DBUG_PRINT("info", ("Reading user information over SSL layer"));
|
||||
if ((pkt_len=my_net_read(net)) == packet_error ||
|
||||
pkt_len < NORMAL_HANDSHAKE_SIZE)
|
||||
|
@ -1173,18 +1173,46 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_CONNECT_GOOD:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_CB_HITS:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_HITS:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_CACHE_FULL:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_MISSES:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_TIMEOUTS:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_NUMBER:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_CONNECT:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context_));
|
||||
break;
|
||||
case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE:
|
||||
net_store_data(&packet2,(uint32)
|
||||
SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context_));
|
||||
@ -1246,6 +1274,23 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
|
||||
break;
|
||||
case SHOW_SSL_GET_CIPHER:
|
||||
net_store_data(&packet2, thd->net.vio->ssl_ ? SSL_get_cipher(thd->net.vio->ssl_) : "");
|
||||
case SHOW_SSL_GET_CIPHER_LIST:
|
||||
if(thd->net.vio->ssl_)
|
||||
{
|
||||
char buf[1024]="";
|
||||
for (int i=0; ; i++)
|
||||
{
|
||||
const char *p=SSL_get_cipher_list(thd->net.vio->ssl_,i);
|
||||
if (p == NULL)
|
||||
break;
|
||||
if (i != 0)
|
||||
strcat(buf,":");
|
||||
strcat(buf,p);
|
||||
DBUG_PRINT("info",("cipher to add: %s,%s",p,buf));
|
||||
}
|
||||
net_store_data(&packet2, buf);
|
||||
} else
|
||||
net_store_data(&packet2, "");
|
||||
break;
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
@ -285,6 +285,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
||||
%token SERIALIZABLE_SYM
|
||||
%token SESSION_SYM
|
||||
%token SHUTDOWN
|
||||
%token SSL_SYM
|
||||
%token STARTING
|
||||
%token STATUS_SYM
|
||||
%token STRAIGHT_JOIN
|
||||
@ -316,6 +317,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
||||
%token WHERE
|
||||
%token WITH
|
||||
%token WRITE_SYM
|
||||
%token X509_SYM
|
||||
%token COMPRESSED_SYM
|
||||
|
||||
%token BIGINT
|
||||
@ -3265,10 +3267,11 @@ grant:
|
||||
lex->columns.empty();
|
||||
lex->grant= lex->grant_tot_col=0;
|
||||
lex->select->db=0;
|
||||
lex->ssl_chipher=lex->ssl_subject=lex->ssl_issuer=0;
|
||||
lex->ssl_type=SSL_TYPE_NONE;
|
||||
lex->ssl_cipher=lex->x509_subject=lex->x509_issuer=0;
|
||||
}
|
||||
grant_privileges ON opt_table TO_SYM user_list
|
||||
grant_option require_clause
|
||||
require_clause grant_option
|
||||
|
||||
grant_privileges:
|
||||
grant_privilege_list {}
|
||||
@ -3302,25 +3305,32 @@ grant_privilege:
|
||||
| FILE_SYM { Lex->grant |= FILE_ACL;}
|
||||
| GRANT OPTION { Lex->grant |= GRANT_ACL;}
|
||||
|
||||
require_clause: /* empty */
|
||||
| REQUIRE_SYM require_list
|
||||
|
||||
|
||||
require_list: require_list_element AND require_list
|
||||
| require_list_element
|
||||
|
||||
|
||||
require_list_element: SUBJECT_SYM TEXT_STRING
|
||||
{
|
||||
Lex->ssl_subject=$2.str;
|
||||
if (Lex->x509_subject) {
|
||||
send_error(&Lex->thd->net,ER_GRANT_DUPL_SUBJECT);
|
||||
YYABORT;
|
||||
} else
|
||||
Lex->x509_subject=$2.str;
|
||||
}
|
||||
| ISSUER_SYM TEXT_STRING
|
||||
{
|
||||
Lex->ssl_issuer=$2.str;
|
||||
if (Lex->x509_issuer) {
|
||||
send_error(&Lex->thd->net,ER_GRANT_DUPL_ISSUER);
|
||||
YYABORT;
|
||||
} else
|
||||
Lex->x509_issuer=$2.str;
|
||||
}
|
||||
| CIPHER_SYM TEXT_STRING
|
||||
{
|
||||
Lex->ssl_chipher=$2.str;
|
||||
if (Lex->ssl_cipher) {
|
||||
send_error(&Lex->thd->net,ER_GRANT_DUPL_CIPHER);
|
||||
YYABORT;
|
||||
} else
|
||||
Lex->ssl_cipher=$2.str;
|
||||
}
|
||||
|
||||
opt_table:
|
||||
@ -3429,16 +3439,18 @@ column_list_id:
|
||||
|
||||
|
||||
require_clause: /* empty */
|
||||
| REQUIRE_SYM require_list { /* do magic */}
|
||||
|
||||
require_list: require_list_element AND require_list
|
||||
{ /* do magic */}
|
||||
| require_list_element {/*do magic*/}
|
||||
|
||||
require_list_element: SUBJECT_SYM TEXT_STRING
|
||||
| ISSUER TEXT_STRING
|
||||
| CIPHER TEXT_STRING
|
||||
|
||||
| REQUIRE_SYM require_list
|
||||
{
|
||||
Lex->ssl_type=SSL_TYPE_SPECIFIED;
|
||||
}
|
||||
| REQUIRE_SYM SSL_SYM
|
||||
{
|
||||
Lex->ssl_type=SSL_TYPE_ANY;
|
||||
}
|
||||
| REQUIRE_SYM X509_SYM
|
||||
{
|
||||
Lex->ssl_type=SSL_TYPE_X509;
|
||||
}
|
||||
|
||||
grant_option:
|
||||
/* empty */ {}
|
||||
|
@ -134,7 +134,11 @@ enum SHOW_TYPE { SHOW_LONG,SHOW_CHAR,SHOW_INT,SHOW_CHAR_PTR,SHOW_BOOL,
|
||||
,SHOW_SSL_CTX_SESS_GET_CACHE_SIZE, SHOW_SSL_GET_CIPHER
|
||||
,SHOW_SSL_GET_DEFAULT_TIMEOUT, SHOW_SSL_GET_VERIFY_MODE
|
||||
,SHOW_SSL_CTX_GET_VERIFY_MODE, SHOW_SSL_GET_VERIFY_DEPTH
|
||||
,SHOW_SSL_CTX_GET_VERIFY_DEPTH
|
||||
,SHOW_SSL_CTX_GET_VERIFY_DEPTH, SHOW_SSL_CTX_SESS_CONNECT
|
||||
,SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE, SHOW_SSL_CTX_SESS_CONNECT_GOOD
|
||||
,SHOW_SSL_CTX_SESS_HITS, SHOW_SSL_CTX_SESS_MISSES
|
||||
,SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL
|
||||
,SHOW_SSL_GET_CIPHER_LIST
|
||||
#endif /* HAVE_OPENSSL */
|
||||
};
|
||||
|
||||
|
@ -41,6 +41,7 @@ main( int argc,
|
||||
char* server_key = 0, *server_cert = 0;
|
||||
char* client_key = 0, *client_cert = 0;
|
||||
char* ca_file = 0, *ca_path = 0;
|
||||
char* cipher=0;
|
||||
int child_pid,sv[2];
|
||||
struct st_VioSSLAcceptorFd* ssl_acceptor=0;
|
||||
struct st_VioSSLConnectorFd* ssl_connector=0;
|
||||
@ -74,17 +75,17 @@ main( int argc,
|
||||
if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1)
|
||||
fatal_error("socketpair");
|
||||
|
||||
ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path);
|
||||
ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path);
|
||||
ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path, cipher);
|
||||
ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher);
|
||||
|
||||
client_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0));
|
||||
client_vio->sd = sv[0];
|
||||
client_vio->vioblocking(client_vio,0);
|
||||
sslconnect(ssl_connector,client_vio);
|
||||
sslconnect(ssl_connector,client_vio,60L);
|
||||
server_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0));
|
||||
server_vio->sd = sv[1];
|
||||
server_vio->vioblocking(client_vio,0);
|
||||
sslaccept(ssl_acceptor,server_vio);
|
||||
sslaccept(ssl_acceptor,server_vio,60L);
|
||||
|
||||
printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd);
|
||||
|
||||
|
@ -32,7 +32,7 @@ main( int argc __attribute__((unused)),
|
||||
char** argv)
|
||||
{
|
||||
char client_key[] = "../SSL/client-key.pem", client_cert[] = "../SSL/client-cert.pem";
|
||||
char ca_file[] = "../SSL/cacert.pem", *ca_path = 0;
|
||||
char ca_file[] = "../SSL/cacert.pem", *ca_path = 0, *cipher=0;
|
||||
struct st_VioSSLConnectorFd* ssl_connector=0;
|
||||
struct sockaddr_in sa;
|
||||
Vio* client_vio=0;
|
||||
@ -48,7 +48,7 @@ main( int argc __attribute__((unused)),
|
||||
if (ca_path!=0)
|
||||
printf("CApath : %s\n", ca_path);
|
||||
|
||||
ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path);
|
||||
ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher);
|
||||
if(!ssl_connector) {
|
||||
fatal_error("client:new_VioSSLConnectorFd failed");
|
||||
}
|
||||
@ -69,7 +69,7 @@ main( int argc __attribute__((unused)),
|
||||
/* ----------------------------------------------- */
|
||||
/* Now we have TCP conncetion. Start SSL negotiation. */
|
||||
read(client_vio->sd,xbuf, sizeof(xbuf));
|
||||
sslconnect(ssl_connector,client_vio);
|
||||
sslconnect(ssl_connector,client_vio,60L);
|
||||
err = client_vio->read(client_vio,xbuf, sizeof(xbuf));
|
||||
if (err<=0) {
|
||||
my_free((gptr)ssl_connector,MYF(0));
|
||||
|
@ -46,7 +46,7 @@ do_ssl_stuff( TH_ARGS* args)
|
||||
/* TCP connection is ready. Do server side SSL. */
|
||||
|
||||
err = write(server_vio->sd,(gptr)s, strlen(s));
|
||||
sslaccept(args->ssl_acceptor,server_vio);
|
||||
sslaccept(args->ssl_acceptor,server_vio,60L);
|
||||
err = server_vio->write(server_vio,(gptr)s, strlen(s));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -65,7 +65,8 @@ main( int argc __attribute__((unused)),
|
||||
char server_key[] = "../SSL/server-key.pem",
|
||||
server_cert[] = "../SSL/server-cert.pem";
|
||||
char ca_file[] = "../SSL/cacert.pem",
|
||||
*ca_path = 0;
|
||||
*ca_path = 0,
|
||||
*cipher = 0;
|
||||
struct st_VioSSLAcceptorFd* ssl_acceptor;
|
||||
pthread_t th;
|
||||
TH_ARGS th_args;
|
||||
@ -89,7 +90,7 @@ main( int argc __attribute__((unused)),
|
||||
if (ca_path!=0)
|
||||
printf("CApath : %s\n", ca_path);
|
||||
|
||||
th_args.ssl_acceptor = ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path);
|
||||
th_args.ssl_acceptor = ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path,cipher);
|
||||
|
||||
/* ----------------------------------------------- */
|
||||
/* Prepare TCP socket for receiving connections */
|
||||
|
@ -137,7 +137,7 @@ int vio_write(Vio * vio, const gptr buf, int size)
|
||||
}
|
||||
|
||||
|
||||
int vio_blocking(Vio * vio, my_bool set_blocking_mode)
|
||||
int vio_blocking(Vio * vio __attribute__((unused)), my_bool set_blocking_mode)
|
||||
{
|
||||
int r=0;
|
||||
DBUG_ENTER("vio_blocking");
|
||||
|
122
vio/viossl.c
122
vio/viossl.c
@ -118,8 +118,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);
|
||||
@ -207,7 +210,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;
|
||||
@ -298,12 +300,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 +317,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 +338,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 +372,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 +401,7 @@ int i;
|
||||
} else
|
||||
DBUG_PRINT("info",("Server does not have certificate."));
|
||||
#endif
|
||||
vio_blocking(vio, blocking);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_OPENSSL */
|
||||
|
@ -168,15 +168,17 @@ vio_verify_callback(int ok, X509_STORE_CTX *ctx)
|
||||
struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file,
|
||||
const char* cert_file,
|
||||
const char* ca_file,
|
||||
const char* ca_path)
|
||||
const char* ca_path,
|
||||
const char* cipher)
|
||||
{
|
||||
int verify = SSL_VERIFY_PEER;
|
||||
struct st_VioSSLConnectorFd* ptr;
|
||||
int result;
|
||||
DH *dh=NULL;
|
||||
DBUG_ENTER("new_VioSSLConnectorFd");
|
||||
DBUG_PRINT("enter",
|
||||
("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s",
|
||||
key_file, cert_file, ca_path, ca_file));
|
||||
("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s",
|
||||
key_file, cert_file, ca_path, ca_file, cipher));
|
||||
ptr=(struct st_VioSSLConnectorFd*)my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0));
|
||||
ptr->ssl_context_=0;
|
||||
ptr->ssl_method_=0;
|
||||
@ -206,8 +208,12 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file,
|
||||
/*
|
||||
* SSL_CTX_set_options
|
||||
* SSL_CTX_set_info_callback
|
||||
* SSL_CTX_set_cipher_list
|
||||
*/
|
||||
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_verify(ptr->ssl_context_, verify, vio_verify_callback);
|
||||
if (vio_set_cert_stuff(ptr->ssl_context_, cert_file, key_file) == -1)
|
||||
{
|
||||
@ -231,14 +237,6 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file,
|
||||
SSL_CTX_set_tmp_dh(ptr->ssl_context_,dh);
|
||||
DH_free(dh);
|
||||
|
||||
/*if (cipher != NULL)
|
||||
if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
|
||||
BIO_printf(bio_err,"error setting cipher list\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
*/
|
||||
|
||||
DBUG_RETURN(ptr);
|
||||
ctor_failure:
|
||||
DBUG_PRINT("exit", ("there was an error"));
|
||||
@ -253,18 +251,20 @@ struct st_VioSSLAcceptorFd*
|
||||
new_VioSSLAcceptorFd(const char* key_file,
|
||||
const char* cert_file,
|
||||
const char* ca_file,
|
||||
const char* ca_path)
|
||||
const char* ca_path,
|
||||
const char* cipher)
|
||||
{
|
||||
int verify = (SSL_VERIFY_PEER |
|
||||
SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
|
||||
SSL_VERIFY_CLIENT_ONCE);
|
||||
|
||||
struct st_VioSSLAcceptorFd* ptr;
|
||||
int result;
|
||||
DH *dh=NULL;
|
||||
DBUG_ENTER("new_VioSSLAcceptorFd");
|
||||
DBUG_PRINT("enter",
|
||||
("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s",
|
||||
key_file, cert_file, ca_path, ca_file));
|
||||
("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s",
|
||||
key_file, cert_file, ca_path, ca_file, cipher));
|
||||
|
||||
ptr=(struct st_VioSSLAcceptorFd*)my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0));
|
||||
ptr->ssl_context_=0;
|
||||
@ -293,12 +293,19 @@ new_VioSSLAcceptorFd(const char* key_file,
|
||||
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);
|
||||
@ -328,14 +335,6 @@ new_VioSSLAcceptorFd(const char* key_file,
|
||||
SSL_CTX_set_tmp_dh(ptr->ssl_context_,dh);
|
||||
DH_free(dh);
|
||||
|
||||
/*if (cipher != NULL)
|
||||
if(!SSL_CTX_set_cipher_list(ctx,cipher)) {
|
||||
BIO_printf(bio_err,"error setting cipher list\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
*/
|
||||
|
||||
DBUG_RETURN(ptr);
|
||||
ctor_failure:
|
||||
DBUG_PRINT("exit", ("there was an error"));
|
||||
|
Loading…
x
Reference in New Issue
Block a user