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:
unknown 2001-09-30 10:46:20 +08:00
parent 5e0851e1b3
commit d13f2dfdeb
59 changed files with 646 additions and 267 deletions

View File

@ -8,6 +8,6 @@ extra_configs="$pentium_configs"
strip=yes strip=yes
extra_configs="$extra_configs --with-innodb --with-berkeley-db \ extra_configs="$extra_configs --with-innodb --with-berkeley-db \
--enable-thread-safe-client" --enable-thread-safe-client --with-openssl --with-vio"
. "$path/FINISH.sh" . "$path/FINISH.sh"

View File

@ -3187,7 +3187,7 @@ encounter per year, but we are as always very flexible towards our customers!
@c @image{Flags/estonia} Estonia [Tradenet] @ @c @image{Flags/estonia} Estonia [Tradenet] @
@c @uref{http://mysql.tradenet.ee, WWW} @c @uref{http://mysql.tradenet.ee, WWW}
@item @item
@c EMAIL: tonu@spamm.ee (Tonu Samuel) @c EMAIL: tonu@spam.ee (Tonu Samuel)
@image{Flags/estonia} Estonia [OKinteractive] @ @image{Flags/estonia} Estonia [OKinteractive] @
@uref{http://mysql.mirror.ok.ee, WWW} @uref{http://mysql.mirror.ok.ee, WWW}
@item @item

View File

@ -15583,7 +15583,7 @@ Users of Java JDBC:
Do not transmit plain (unencrypted) data over the Internet. These data are 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 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 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) SSH port-forwarding can be used to create an encrypted (and compressed)
tunnel for the communication. tunnel for the communication.
@item @item
@ -16985,7 +16985,11 @@ GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
ON @{tbl_name | * | *.* | db_name.*@} ON @{tbl_name | * | *.* | db_name.*@}
TO user_name [IDENTIFIED BY 'password'] TO user_name [IDENTIFIED BY 'password']
[, 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] [WITH GRANT OPTION]
REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...] 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. MySQL grant tables.
@end itemize @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 @node User names, Privilege changes, GRANT, User Account Management
@subsection MySQL User Names and Passwords @subsection MySQL User Names and Passwords
@ -19830,7 +19948,7 @@ differ somewhat:
| have_bdb | YES | | have_bdb | YES |
| have_innodb | YES | | have_innodb | YES |
| have_raid | YES | | have_raid | YES |
| have_ssl | NO | | have_openssl | NO |
| init_file | | | init_file | |
| interactive_timeout | 28800 | | interactive_timeout | 28800 |
| join_buffer_size | 131072 | | join_buffer_size | 131072 |
@ -20017,7 +20135,7 @@ if @code{--skip-bdb} is used.
if @code{--skip-innodb} is used. if @code{--skip-innodb} is used.
@item @code{have_raid} @item @code{have_raid}
@code{YES} if @code{mysqld} supports the @code{RAID} option. @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 @code{YES} if @code{mysqld} supports SSL (encryption) on the client/server
protocol. protocol.
@ -21651,7 +21769,7 @@ mysql> show variables like "have_%";
| have_innodb | NO | | have_innodb | NO |
| have_isam | YES | | have_isam | YES |
| have_raid | NO | | have_raid | NO |
| have_ssl | NO | | have_openssl | NO |
+---------------+-------+ +---------------+-------+
@end example @end example
@ -48296,7 +48414,7 @@ Allow hex constants in the @code{--fields-*-by} and
Added option @code{--safe-show-database} to @code{mysqld}. Added option @code{--safe-show-database} to @code{mysqld}.
@item @item
Added @code{have_bdb}, @code{have_gemini}, @code{have_innobase}, 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. easy to test for supported extensions.
@item @item
Added option @code{--open-files-limit} to @code{mysqld}. Added option @code{--open-files-limit} to @code{mysqld}.

View File

@ -663,7 +663,7 @@ if test "$cpu_vendor" = "AuthenticAMD"; then
fi fi
elif test "$cpu_vendor" = "GenuineIntel"; then elif test "$cpu_vendor" = "GenuineIntel"; then
if test $cpu_family>=6; 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 elif test $cpu_family=5; then
cpu_set="pentium i486 i386"; cpu_set="pentium i486 i386";
elif test $cpu_family=4; then elif test $cpu_family=4; then
@ -682,9 +682,9 @@ done
if test "$mysql_cv_cpu" = "unknown" if test "$mysql_cv_cpu" = "unknown"
then then
CFLAGS="$ac_save_CFLAGS" CFLAGS="$ac_save_CFLAGS"
AC_MSG_RESULT(none) AC_MSG_RESULT(none)
else else
AC_MSG_RESULT($mysql_cv_cpu) AC_MSG_RESULT($mysql_cv_cpu)
fi fi
])) ]))

View File

@ -24,6 +24,7 @@
* Jani Tolonen <jani@mysql.com> * Jani Tolonen <jani@mysql.com>
* Matt Wagner <mwagner@mysql.com> * Matt Wagner <mwagner@mysql.com>
* Jeremy Cole <jcole@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) { if (field_names) {
for (i=0; field_names[i]; i++) { for (i=0; field_names[i]; i++) {
for (j=0; field_names[i][j]; j++) { 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 #ifdef HAVE_OPENSSL
if (opt_use_ssl) if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath); opt_ssl_capath, opt_ssl_cipher);
#endif #endif
if (safe_updates) if (safe_updates)
{ {

View File

@ -265,7 +265,7 @@ int main(int argc,char *argv[])
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (opt_use_ssl) if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, 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 */ #endif /* HAVE_OPENSSL */
if (sql_connect(&mysql,host,user,opt_password,option_wait)) if (sql_connect(&mysql,host,user,opt_password,option_wait))
error = 1; error = 1;

View File

@ -591,7 +591,7 @@ static int dbConnect(char *host, char *user, char *passwd)
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (opt_use_ssl) if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath); opt_ssl_capath, opt_ssl_cipher);
#endif #endif
if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd, if (!(sock = mysql_real_connect(&mysql_connection, host, user, passwd,
NULL, opt_mysql_port, opt_mysql_unix_port, 0))) NULL, opt_mysql_port, opt_mysql_unix_port, 0)))

View File

@ -523,7 +523,7 @@ static int dbConnect(char *host, char *user,char *passwd)
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (opt_use_ssl) if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath); opt_ssl_capath, opt_ssl_cipher);
#endif #endif
if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd, if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
NULL,opt_mysql_port,opt_mysql_unix_port, NULL,opt_mysql_port,opt_mysql_unix_port,

View File

@ -400,7 +400,7 @@ static MYSQL *db_connect(char *host, char *database, char *user, char *passwd)
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (opt_use_ssl) if (opt_use_ssl)
mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, mysql_ssl_set(&mysql_connection, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath); opt_ssl_capath, opt_ssl_cipher);
#endif #endif
if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd, if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd,
database,opt_mysql_port,opt_mysql_unix_port, database,opt_mysql_port,opt_mysql_unix_port,

View File

@ -87,7 +87,7 @@ int main(int argc, char **argv)
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (opt_use_ssl) if (opt_use_ssl)
mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, mysql_ssl_set(&mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca,
opt_ssl_capath); opt_ssl_capath, opt_ssl_cipher);
#endif #endif
if (!(mysql_real_connect(&mysql,host,user,opt_password, if (!(mysql_real_connect(&mysql,host,user,opt_password,
argv[0],opt_mysql_port,opt_mysql_unix_port, argv[0],opt_mysql_port,opt_mysql_unix_port,

View File

@ -135,6 +135,7 @@ struct st_mysql_options {
char *ssl_cert; /* PEM cert file */ char *ssl_cert; /* PEM cert file */
char *ssl_ca; /* PEM CA file */ char *ssl_ca; /* PEM CA file */
char *ssl_capath; /* PEM directory of CA-s? */ 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 use_ssl; /* if to use SSL or not */
my_bool compress,named_pipe; my_bool compress,named_pipe;
/* /*
@ -262,7 +263,7 @@ const char * STDCALL mysql_character_set_name(MYSQL *mysql);
MYSQL * STDCALL mysql_init(MYSQL *mysql); MYSQL * STDCALL mysql_init(MYSQL *mysql);
int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key, int STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,
const char *cert, const char *ca, const char *cert, const char *ca,
const char *capath); const char *capath, const char *cipher);
int STDCALL mysql_ssl_clear(MYSQL *mysql); int STDCALL mysql_ssl_clear(MYSQL *mysql);
my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user,
const char *passwd, const char *db); const char *passwd, const char *db);

View File

@ -221,4 +221,7 @@
#define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1218 #define ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT 1218
#define ER_CANT_UPDATE_WITH_READLOCK 1219 #define ER_CANT_UPDATE_WITH_READLOCK 1219
#define ER_MIXING_NOT_ALLOWED 1220 #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

View File

@ -39,4 +39,10 @@
my_free(opt_ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
opt_ssl_ca = my_strdup(optarg, MYF(0)); opt_ssl_ca = my_strdup(optarg, MYF(0));
break; 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 #endif

View File

@ -22,10 +22,12 @@
#define OPT_SSL_CERT 202 #define OPT_SSL_CERT 202
#define OPT_SSL_CA 203 #define OPT_SSL_CA 203
#define OPT_SSL_CAPATH 204 #define OPT_SSL_CAPATH 204
#define OPT_SSL_CIPHER 205
{"ssl", no_argument, 0, OPT_SSL_SSL}, {"ssl", no_argument, 0, OPT_SSL_SSL},
{"ssl-key", required_argument, 0, OPT_SSL_KEY}, {"ssl-key", required_argument, 0, OPT_SSL_KEY},
{"ssl-cert", required_argument, 0, OPT_SSL_CERT}, {"ssl-cert", required_argument, 0, OPT_SSL_CERT},
{"ssl-ca", required_argument, 0, OPT_SSL_CA}, {"ssl-ca", required_argument, 0, OPT_SSL_CA},
{"ssl-capath", required_argument, 0, OPT_SSL_CAPATH}, {"ssl-capath", required_argument, 0, OPT_SSL_CAPATH},
{"ssl-cipher", required_argument, 0, OPT_SSL_CIPHER},
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */

View File

@ -21,5 +21,6 @@
--ssl-key X509 key in PEM format (implies --ssl)\n\ --ssl-key X509 key in PEM format (implies --ssl)\n\
--ssl-cert X509 cert 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-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 #endif

View File

@ -21,4 +21,5 @@ static char *opt_ssl_key = 0;
static char *opt_ssl_cert = 0; static char *opt_ssl_cert = 0;
static char *opt_ssl_ca = 0; static char *opt_ssl_ca = 0;
static char *opt_ssl_capath = 0; static char *opt_ssl_capath = 0;
static char *opt_ssl_cipher = 0;
#endif #endif

View File

@ -169,9 +169,6 @@ struct st_VioSSLAcceptorFd
state_connect = 1, state_connect = 1,
state_accept = 2 state_accept = 2
}; };
// BIO* bio_;
// char desc_[100];
// Vio* sd_;
/* function pointers which are only once for SSL server /* function pointers which are only once for SSL server
Vio*(*sslaccept)(struct st_VioSSLAcceptorFd*,Vio*); */ Vio*(*sslaccept)(struct st_VioSSLAcceptorFd*,Vio*); */
@ -184,15 +181,17 @@ struct st_VioSSLConnectorFd
SSL_METHOD* ssl_method_; SSL_METHOD* ssl_method_;
/* function pointers which are only once for SSL client */ /* function pointers which are only once for SSL client */
}; };
void sslaccept(struct st_VioSSLAcceptorFd*, Vio*); void sslaccept(struct st_VioSSLAcceptorFd*, Vio*, long timeout);
void sslconnect(struct st_VioSSLConnectorFd*, Vio*); void sslconnect(struct st_VioSSLConnectorFd*, Vio*, long timeout);
struct st_VioSSLConnectorFd struct st_VioSSLConnectorFd
*new_VioSSLConnectorFd(const char* key_file, const char* cert_file, *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 struct st_VioSSLAcceptorFd
*new_VioSSLAcceptorFd(const char* key_file, const char* cert_file, *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); Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state);
#ifdef __cplusplus #ifdef __cplusplus
@ -200,6 +199,9 @@ Vio* new_VioSSL(struct st_VioSSLAcceptorFd* fd, Vio* sd,int state);
#endif #endif
#endif /* HAVE_OPENSSL */ #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 #ifndef EMBEDDED_LIBRARY
/* This structure is for every connection on both sides */ /* This structure is for every connection on both sides */
struct st_vio struct st_vio
@ -229,10 +231,8 @@ struct st_vio
my_bool (*poll_read)(Vio*,uint); my_bool (*poll_read)(Vio*,uint);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
BIO* bio_;
SSL* ssl_; SSL* ssl_;
my_bool open_; my_bool open_;
char *ssl_cip_;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
#endif /* HAVE_VIO */ #endif /* HAVE_VIO */
}; };

View File

@ -695,7 +695,7 @@ mysql_free_result(MYSQL_RES *result)
static const char *default_options[]= static const char *default_options[]=
{"port","socket","compress","password","pipe", "timeout", "user", {"port","socket","compress","password","pipe", "timeout", "user",
"init-command", "host", "database", "debug", "return-found-rows", "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", "character-set-dir", "default-character-set", "interactive-timeout",
"connect_timeout", "replication-probe", "enable-reads-from-master", "connect_timeout", "replication-probe", "enable-reads-from-master",
"repl-parse-query", "repl-parse-query",
@ -1368,15 +1368,17 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
const char *key __attribute__((unused)), const char *key __attribute__((unused)),
const char *cert __attribute__((unused)), const char *cert __attribute__((unused)),
const char *ca __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 #ifdef HAVE_OPENSSL
mysql->options.ssl_key = key==0 ? 0 : my_strdup(key,MYF(0)); 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_cert = cert==0 ? 0 : my_strdup(cert,MYF(0));
mysql->options.ssl_ca = ca==0 ? 0 : my_strdup(ca,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_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->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_)); DBUG_PRINT("info",("mysql_ssl_set, context: %p",((struct st_VioSSLConnectorFd *)(mysql->connector_fd))->ssl_context_));
#endif #endif
return 0; 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_cert, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_ca, 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_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_key = 0;
mysql->options.ssl_cert = 0; mysql->options.ssl_cert = 0;
mysql->options.ssl_ca = 0; mysql->options.ssl_ca = 0;
mysql->options.ssl_capath = 0; mysql->options.ssl_capath = 0;
mysql->options.ssl_cipher= 0;
mysql->options.use_ssl = FALSE; mysql->options.use_ssl = FALSE;
my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
mysql->connector_fd = 0; mysql->connector_fd = 0;
@ -1797,7 +1801,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
/* Do the SSL layering. */ /* Do the SSL layering. */
DBUG_PRINT("info", ("IO layer change in progress...")); DBUG_PRINT("info", ("IO layer change in progress..."));
DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_)); 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!")); DBUG_PRINT("info", ("IO layer change done!"));
} }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
@ -1887,7 +1891,7 @@ static my_bool mysql_reconnect(MYSQL *mysql)
if (!mysql->reconnect || if (!mysql->reconnect ||
(mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info) (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; mysql->server_status&= ~SERVER_STATUS_IN_TRANS;
DBUG_RETURN(1); 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.my_cnf_group,MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.charset_dir,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)); 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 */ /* Clear pointers for better safety */
mysql->host_info=mysql->user=mysql->passwd=mysql->db=0; mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
bzero((char*) &mysql->options,sizeof(mysql->options)); bzero((char*) &mysql->options,sizeof(mysql->options));
mysql->net.vio = 0; mysql->net.vio = 0;
#ifdef HAVE_OPENSSL
mysql_ssl_clear(mysql);
#endif /* HAVE_OPENSSL */
/* free/close slave list */ /* free/close slave list */
if (mysql->rpl_pivot) if (mysql->rpl_pivot)

View File

@ -257,7 +257,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
send_error(net,ER_OUT_OF_RESOURCES); send_error(net,ER_OUT_OF_RESOURCES);
return 1; 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, passwd, thd->scramble, &thd->priv_user,
protocol_version == 9 || protocol_version == 9 ||
!(thd->client_capabilities & !(thd->client_capabilities &

View File

@ -134,7 +134,7 @@ then
c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL," 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 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 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 ssl_cipher char(60) NULL,"
c_u="$c_u x509_issuer blob NULL," c_u="$c_u x509_issuer blob NULL,"
c_u="$c_u x509_subject blob NULL," c_u="$c_u x509_subject blob NULL,"

View File

@ -224,18 +224,22 @@ then
c_u="$c_u References_priv enum('N','Y') DEFAULT 'N' NOT NULL," 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 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 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 PRIMARY KEY Host (Host,User)"
c_u="$c_u )" c_u="$c_u )"
c_u="$c_u comment='Users and global privileges';" 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'); 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'); 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 ('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'); 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 ('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');" INSERT INTO user VALUES ('$hostname','','','N','N','N','N','N','N','N','N','N','N','N','N','N','N','NONE',NULL,NULL,NULL);"
fi fi
if test ! -f $mdata/func.frm if test ! -f $mdata/func.frm

View File

@ -319,6 +319,7 @@ static SYMBOL symbols[] = {
{ "SQL_SLAVE_SKIP_COUNTER", SYM(SQL_SLAVE_SKIP_COUNTER),0,0}, { "SQL_SLAVE_SKIP_COUNTER", SYM(SQL_SLAVE_SKIP_COUNTER),0,0},
{ "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0}, { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0},
{ "SQL_WARNINGS", SYM(SQL_WARNINGS),0,0}, { "SQL_WARNINGS", SYM(SQL_WARNINGS),0,0},
{ "SSL", SYM(SSL_SYM),0,0},
{ "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0}, { "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0},
{ "START", SYM(START_SYM),0,0}, { "START", SYM(START_SYM),0,0},
{ "STARTING", SYM(STARTING),0,0}, { "STARTING", SYM(STARTING),0,0},
@ -362,6 +363,7 @@ static SYMBOL symbols[] = {
{ "WRITE", SYM(WRITE_SYM),0,0}, { "WRITE", SYM(WRITE_SYM),0,0},
{ "WHEN", SYM(WHEN_SYM),0,0}, { "WHEN", SYM(WHEN_SYM),0,0},
{ "WHERE", SYM(WHERE),0,0}, { "WHERE", SYM(WHERE),0,0},
{ "X509", SYM(X509_SYM),0,0},
{ "YEAR", SYM(YEAR_SYM),0,0}, { "YEAR", SYM(YEAR_SYM),0,0},
{ "YEAR_MONTH", SYM(YEAR_MONTH_SYM),0,0}, { "YEAR_MONTH", SYM(YEAR_MONTH_SYM),0,0},
{ "ZEROFILL", SYM(ZEROFILL),0,0}, { "ZEROFILL", SYM(ZEROFILL),0,0},

View File

@ -803,7 +803,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
/* Do the SSL layering. */ /* Do the SSL layering. */
DBUG_PRINT("info", ("IO layer change in progress...")); DBUG_PRINT("info", ("IO layer change in progress..."));
DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_)); 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!")); DBUG_PRINT("info", ("IO layer change done!"));
} }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */

View File

@ -242,16 +242,11 @@ static char **defaults_argv,time_zone[30];
static const char *default_table_type_name; static const char *default_table_type_name;
static char glob_hostname[FN_REFLEN]; static char glob_hostname[FN_REFLEN];
#include "sslopt-vars.h"
#ifdef HAVE_OPENSSL #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; struct st_VioSSLAcceptorFd * ssl_acceptor_fd = 0;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
I_List <i_string_pair> replicate_rewrite_db; I_List <i_string_pair> replicate_rewrite_db;
I_List<i_string> replicate_do_db, replicate_ignore_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 // 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_cert,MYF(MY_ALLOW_ZERO_PTR));
my_free(opt_ssl_ca,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_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; opt_ssl_key=opt_ssl_cert=opt_ssl_ca=opt_ssl_capath=0;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
free_defaults(defaults_argv); free_defaults(defaults_argv);
@ -1712,7 +1708,7 @@ int main(int argc, char **argv)
if (opt_use_ssl) if (opt_use_ssl)
{ {
ssl_acceptor_fd = new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, 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)); DBUG_PRINT("info",("ssl_acceptor_fd: %p",ssl_acceptor_fd));
if (!ssl_acceptor_fd) if (!ssl_acceptor_fd)
opt_use_ssl=0; opt_use_ssl=0;
@ -3110,21 +3106,29 @@ struct show_var_st status_vars[]= {
{"Sort_rows", (char*) &filesort_rows, SHOW_LONG}, {"Sort_rows", (char*) &filesort_rows, SHOW_LONG},
{"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG}, {"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG},
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
{"SSL_CTX_sess_accept", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT}, {"ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT},
{"SSL_CTX_sess_accept_good", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD}, {"ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD},
{"SSL_CTX_sess_accept_renegotiate", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE}, {"ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD},
{"SSL_CTX_sess_cb_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS}, {"ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE},
{"SSL_CTX_sess_number", (char*) 0, SHOW_SSL_CTX_SESS_NUMBER}, {"ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE},
{"SSL_CTX_get_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE}, {"ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS},
{"SSL_CTX_sess_get_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE}, {"ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS},
{"SSL_CTX_get_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE}, {"ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES},
{"SSL_CTX_get_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH}, {"ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS},
{"SSL_get_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE}, {"ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER},
{"SSL_get_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH}, {"ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT},
{"SSL_session_reused", (char*) 0, SHOW_SSL_SESSION_REUSED}, {"ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL},
{"SSL_get_version", (char*) 0, SHOW_SSL_GET_VERSION}, {"ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE},
{"SSL_get_cipher", (char*) 0, SHOW_SSL_GET_CIPHER}, {"ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE},
{"SSL_get_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT}, {"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 */ #endif /* HAVE_OPENSSL */
{"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
{"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},

View File

@ -231,3 +231,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -225,3 +225,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -228,3 +228,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -222,3 +222,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -226,3 +226,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -222,3 +222,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -225,3 +225,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -222,3 +222,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -224,3 +224,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -222,3 +222,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -224,3 +224,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -222,3 +222,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -224,3 +224,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -224,3 +224,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -226,3 +226,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -222,3 +222,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -226,3 +226,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -225,3 +225,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -230,3 +230,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -223,3 +223,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -222,3 +222,6 @@
"SELECT kommandona har olika antal kolumner" "SELECT kommandona har olika antal kolumner"
"Kan inte utföra kommandot emedan du har ett READ lås", "Kan inte utföra kommandot emedan du har ett READ lås",
"Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat", "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",

View File

@ -227,3 +227,6 @@
"The used SELECT statements have a different number of columns", "The used SELECT statements have a different number of columns",
"Can't execute the query because you have a conflicting read lock", "Can't execute the query because you have a conflicting read lock",
"Mixing of transactional and non-transactional tables is disabled", "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",

View File

@ -62,8 +62,9 @@ public:
char *user,*password; char *user,*password;
ulong salt[2]; ulong salt[2];
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
char *ssl_type, *ssl_cipher, *x509_issuer, *x509_subject; enum SSL_type ssl_type;
#endif const char *ssl_cipher, *x509_issuer, *x509_subject;
#endif /* HAVE_OPENSSL */
}; };
class ACL_DB :public ACL_ACCESS 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); user.password=get_field(&mem, table,2);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
DBUG_PRINT("info",("table->fields=%d",table->fields)); DBUG_PRINT("info",("table->fields=%d",table->fields));
if (table->fields >= 21) { if (table->fields >= 21) { /* From 4.0.0 we have more fields */
user.ssl_type=get_field(&mem, table,17); 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.ssl_cipher=get_field(&mem, table,18);
user.x509_issuer=get_field(&mem, table,19); user.x509_issuer=get_field(&mem, table,19);
user.x509_subject=get_field(&mem, table,20); user.x509_subject=get_field(&mem, table,20);
} }
#endif #endif /* HAVE_OPENSSL */
if (user.password && (length=(uint) strlen(user.password)) == 8 && if (user.password && (length=(uint) strlen(user.password)) == 8 &&
protocol_version == PROTOCOL_VERSION) 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) */ /* 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,
uint acl_getroot(const char *host, const char *ip, const char *user,
const char *password,const char *message,char **priv_user, const char *password,const char *message,char **priv_user,
bool old_ver) bool old_ver)
{ {
uint user_access=NO_ACCESS; uint user_access=NO_ACCESS;
*priv_user=(char*) user; *priv_user=(char*) user;
char *ptr=0;
if (!initialized) if (!initialized)
return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */ 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, !check_scramble(password,message,acl_user->salt,
(my_bool) old_ver))) (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; user_access=acl_user->access;
#endif /* HAVE_OPENSSL */
if (!acl_user->user) if (!acl_user->user)
*priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */ *priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */
break; 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, 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++) 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->host.hostname && !strcmp(host,acl_user->host.hostname))
{ {
acl_user->access=privileges; 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)
{ {
if (!password[0]) 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, 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) uint privileges)
{ {
ACL_USER acl_user; 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.access=privileges;
acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user); acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user);
acl_user.hostname_length=(uint) strlen(acl_user.host.hostname); 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) if (password)
{ {
acl_user.password=(char*) ""; // Just point at something acl_user.password=(char*) ""; // Just point at something
@ -984,7 +1096,7 @@ static bool test_if_create_new_users(THD *thd)
** Handle GRANT commands ** 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) uint rights, char what, bool create_user)
{ {
int error = -1; int error = -1;
@ -1044,7 +1156,40 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
table->field[i]->store(&what,1); table->field[i]->store(&what,1);
} }
rights=get_access(table,3); 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) if (old_row_exists)
{ {
/* /*
@ -1078,9 +1223,23 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo,
if (!combo.password.str) if (!combo.password.str)
password=0; // No password given on command password=0; // No password given on command
if (old_row_exists) 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 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(); table->file->index_end();
DBUG_RETURN(error); DBUG_RETURN(error);
@ -1626,6 +1785,9 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
TABLE_LIST tables[3]; TABLE_LIST tables[3];
bool create_new_users=0; bool create_new_users=0;
DBUG_ENTER("mysql_table_grant"); 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) if (!initialized)
{ {
@ -1715,9 +1877,10 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
continue; continue;
} }
/* Create user if needed */ /* Create user if needed */
if (replace_user_table(tables[0].table, if (replace_user_table(thd,
*Str, tables[0].table,
0, *Str,
0,
revoke_grant ? 'N' : 'Y', revoke_grant ? 'N' : 'Y',
create_new_users)) create_new_users))
{ {
@ -1810,7 +1973,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list,
pthread_mutex_unlock(&LOCK_grant); pthread_mutex_unlock(&LOCK_grant);
if (!result) if (!result)
send_ok(&thd->net); send_ok(&thd->net);
/* Tables are automaticly closed */ /* Tables are automatically closed */
DBUG_RETURN(result); DBUG_RETURN(result);
} }
@ -1871,7 +2034,8 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights,
result= -1; result= -1;
continue; continue;
} }
if ((replace_user_table(tables[0].table, if ((replace_user_table(thd,
tables[0].table,
*Str, *Str,
(!db ? rights : 0), what, create_new_users))) (!db ? rights : 0), what, create_new_users)))
result= -1; result= -1;
@ -2332,6 +2496,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
{ {
uint counter, want_access,index; uint counter, want_access,index;
int error = 0; int error = 0;
int ssl_options = 0;
ACL_USER *acl_user; ACL_DB *acl_db; ACL_USER *acl_user; ACL_DB *acl_db;
char buff[1024]; char buff[1024];
DBUG_ENTER("mysql_show_grants"); DBUG_ENTER("mysql_show_grants");
@ -2426,30 +2591,37 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user)
global.append('\''); global.append('\'');
} }
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
/* SSL grant stuff */ /* "show grants" SSL related stuff */
DBUG_PRINT("info",("acl_user->ssl_type=%s",acl_user->ssl_type)); if(acl_user->ssl_type==SSL_TYPE_ANY)
DBUG_PRINT("info",("acl_user->ssl_cipher=%s",acl_user->ssl_cipher)); global.append(" REQUIRE SSL",12);
DBUG_PRINT("info",("acl_user->x509_subject=%s",acl_user->x509_subject)); else if(acl_user->ssl_type==SSL_TYPE_X509)
DBUG_PRINT("info",("acl_user->x509_issuer=%s",acl_user->x509_issuer)); global.append(" REQUIRE X509",13);
if(acl_user->ssl_type) { else if(acl_user->ssl_type==SSL_TYPE_SPECIFIED)
if(!strcmp(acl_user->ssl_type,"ssl")) {
global.append(" REQUIRE SSL",12); global.append(" REQUIRE ",9);
else if(!strcmp(acl_user->ssl_type,"x509")) if(acl_user->x509_issuer) {
{ if(ssl_options++)
global.append(" REQUIRE X509 ",14); global.append(" AND ",5);
if(acl_user->x509_issuer) { global.append("ISSUER \"",8);
global.append("SUBJECT \"",9); global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); global.append("\"",1);
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);
}
}
} }
#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) if (want_access & GRANT_ACL)
global.append(" WITH GRANT OPTION",18); global.append(" WITH GRANT OPTION",18);
thd->packet.length(0); thd->packet.length(0);

View File

@ -59,7 +59,7 @@ void acl_reload(void);
void acl_free(bool end=0); void acl_free(bool end=0);
uint acl_get(const char *host, const char *ip, const char *bin_ip, uint acl_get(const char *host, const char *ip, const char *bin_ip,
const char *user, const char *db); 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, const char *password,const char *scramble,char **priv_user,
bool old_ver); bool old_ver);
bool acl_check_host(const char *host, const char *ip); bool acl_check_host(const char *host, const char *ip);

View File

@ -56,7 +56,7 @@ enum enum_sql_command {
SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA, SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA,
SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ, SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ,
SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_MULTI_DELETE, 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, enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT,
@ -145,7 +145,8 @@ typedef struct st_lex {
char *length,*dec,*change,*name; char *length,*dec,*change,*name;
char *backup_dir; /* For RESTORE/BACKUP */ char *backup_dir; /* For RESTORE/BACKUP */
char* to_log; /* For PURGE MASTER LOGS TO */ 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; String *wild;
sql_exchange *exchange; sql_exchange *exchange;

View File

@ -115,7 +115,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user,
send_error(net,ER_OUT_OF_RESOURCES); send_error(net,ER_OUT_OF_RESOURCES);
return 1; 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, passwd, thd->scramble, &thd->priv_user,
protocol_version == 9 || protocol_version == 9 ||
!(thd->client_capabilities & !(thd->client_capabilities &
@ -433,7 +433,7 @@ check_connections(THD *thd)
DBUG_PRINT("info", ("Agreed to change IO layer to SSL") ); DBUG_PRINT("info", ("Agreed to change IO layer to SSL") );
/* Do the SSL layering. */ /* Do the SSL layering. */
DBUG_PRINT("info", ("IO layer change in progress...")); 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")); DBUG_PRINT("info", ("Reading user information over SSL layer"));
if ((pkt_len=my_net_read(net)) == packet_error || if ((pkt_len=my_net_read(net)) == packet_error ||
pkt_len < NORMAL_HANDSHAKE_SIZE) pkt_len < NORMAL_HANDSHAKE_SIZE)

View File

@ -1173,18 +1173,46 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables)
net_store_data(&packet2,(uint32) net_store_data(&packet2,(uint32)
SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context_)); SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context_));
break; 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: case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE:
net_store_data(&packet2,(uint32) net_store_data(&packet2,(uint32)
SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context_)); SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context_));
break; 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: case SHOW_SSL_CTX_SESS_CB_HITS:
net_store_data(&packet2,(uint32) net_store_data(&packet2,(uint32)
SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context_)); SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context_));
break; 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: case SHOW_SSL_CTX_SESS_NUMBER:
net_store_data(&packet2,(uint32) net_store_data(&packet2,(uint32)
SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context_)); SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context_));
break; 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: case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE:
net_store_data(&packet2,(uint32) net_store_data(&packet2,(uint32)
SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context_)); 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; break;
case SHOW_SSL_GET_CIPHER: case SHOW_SSL_GET_CIPHER:
net_store_data(&packet2, thd->net.vio->ssl_ ? SSL_get_cipher(thd->net.vio->ssl_) : ""); 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; break;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */

View File

@ -285,6 +285,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token SERIALIZABLE_SYM %token SERIALIZABLE_SYM
%token SESSION_SYM %token SESSION_SYM
%token SHUTDOWN %token SHUTDOWN
%token SSL_SYM
%token STARTING %token STARTING
%token STATUS_SYM %token STATUS_SYM
%token STRAIGHT_JOIN %token STRAIGHT_JOIN
@ -316,6 +317,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token WHERE %token WHERE
%token WITH %token WITH
%token WRITE_SYM %token WRITE_SYM
%token X509_SYM
%token COMPRESSED_SYM %token COMPRESSED_SYM
%token BIGINT %token BIGINT
@ -3265,10 +3267,11 @@ grant:
lex->columns.empty(); lex->columns.empty();
lex->grant= lex->grant_tot_col=0; lex->grant= lex->grant_tot_col=0;
lex->select->db=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_privileges ON opt_table TO_SYM user_list
grant_option require_clause require_clause grant_option
grant_privileges: grant_privileges:
grant_privilege_list {} grant_privilege_list {}
@ -3302,25 +3305,32 @@ grant_privilege:
| FILE_SYM { Lex->grant |= FILE_ACL;} | FILE_SYM { Lex->grant |= FILE_ACL;}
| GRANT OPTION { Lex->grant |= GRANT_ACL;} | GRANT OPTION { Lex->grant |= GRANT_ACL;}
require_clause: /* empty */
| REQUIRE_SYM require_list
require_list: require_list_element AND require_list require_list: require_list_element AND require_list
| require_list_element | require_list_element
require_list_element: SUBJECT_SYM TEXT_STRING 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 | 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 | 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: opt_table:
@ -3429,16 +3439,18 @@ column_list_id:
require_clause: /* empty */ require_clause: /* empty */
| REQUIRE_SYM require_list { /* do magic */} | REQUIRE_SYM require_list
{
require_list: require_list_element AND require_list Lex->ssl_type=SSL_TYPE_SPECIFIED;
{ /* do magic */} }
| require_list_element {/*do magic*/} | REQUIRE_SYM SSL_SYM
{
require_list_element: SUBJECT_SYM TEXT_STRING Lex->ssl_type=SSL_TYPE_ANY;
| ISSUER TEXT_STRING }
| CIPHER TEXT_STRING | REQUIRE_SYM X509_SYM
{
Lex->ssl_type=SSL_TYPE_X509;
}
grant_option: grant_option:
/* empty */ {} /* empty */ {}

View File

@ -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_CTX_SESS_GET_CACHE_SIZE, SHOW_SSL_GET_CIPHER
,SHOW_SSL_GET_DEFAULT_TIMEOUT, SHOW_SSL_GET_VERIFY_MODE ,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_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 */ #endif /* HAVE_OPENSSL */
}; };

View File

@ -41,6 +41,7 @@ main( int argc,
char* server_key = 0, *server_cert = 0; char* server_key = 0, *server_cert = 0;
char* client_key = 0, *client_cert = 0; char* client_key = 0, *client_cert = 0;
char* ca_file = 0, *ca_path = 0; char* ca_file = 0, *ca_path = 0;
char* cipher=0;
int child_pid,sv[2]; int child_pid,sv[2];
struct st_VioSSLAcceptorFd* ssl_acceptor=0; struct st_VioSSLAcceptorFd* ssl_acceptor=0;
struct st_VioSSLConnectorFd* ssl_connector=0; struct st_VioSSLConnectorFd* ssl_connector=0;
@ -74,17 +75,17 @@ main( int argc,
if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1) if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1)
fatal_error("socketpair"); fatal_error("socketpair");
ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_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); 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 = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0));
client_vio->sd = sv[0]; client_vio->sd = sv[0];
client_vio->vioblocking(client_vio,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 = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0));
server_vio->sd = sv[1]; server_vio->sd = sv[1];
server_vio->vioblocking(client_vio,0); 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); printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd);

View File

@ -32,7 +32,7 @@ main( int argc __attribute__((unused)),
char** argv) char** argv)
{ {
char client_key[] = "../SSL/client-key.pem", client_cert[] = "../SSL/client-cert.pem"; 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 st_VioSSLConnectorFd* ssl_connector=0;
struct sockaddr_in sa; struct sockaddr_in sa;
Vio* client_vio=0; Vio* client_vio=0;
@ -48,7 +48,7 @@ main( int argc __attribute__((unused)),
if (ca_path!=0) if (ca_path!=0)
printf("CApath : %s\n", ca_path); 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) { if(!ssl_connector) {
fatal_error("client:new_VioSSLConnectorFd failed"); fatal_error("client:new_VioSSLConnectorFd failed");
} }
@ -69,7 +69,7 @@ main( int argc __attribute__((unused)),
/* ----------------------------------------------- */ /* ----------------------------------------------- */
/* Now we have TCP conncetion. Start SSL negotiation. */ /* Now we have TCP conncetion. Start SSL negotiation. */
read(client_vio->sd,xbuf, sizeof(xbuf)); 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)); err = client_vio->read(client_vio,xbuf, sizeof(xbuf));
if (err<=0) { if (err<=0) {
my_free((gptr)ssl_connector,MYF(0)); my_free((gptr)ssl_connector,MYF(0));

View File

@ -46,7 +46,7 @@ do_ssl_stuff( TH_ARGS* args)
/* TCP connection is ready. Do server side SSL. */ /* TCP connection is ready. Do server side SSL. */
err = write(server_vio->sd,(gptr)s, strlen(s)); 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)); err = server_vio->write(server_vio,(gptr)s, strlen(s));
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -65,7 +65,8 @@ main( int argc __attribute__((unused)),
char server_key[] = "../SSL/server-key.pem", char server_key[] = "../SSL/server-key.pem",
server_cert[] = "../SSL/server-cert.pem"; server_cert[] = "../SSL/server-cert.pem";
char ca_file[] = "../SSL/cacert.pem", char ca_file[] = "../SSL/cacert.pem",
*ca_path = 0; *ca_path = 0,
*cipher = 0;
struct st_VioSSLAcceptorFd* ssl_acceptor; struct st_VioSSLAcceptorFd* ssl_acceptor;
pthread_t th; pthread_t th;
TH_ARGS th_args; TH_ARGS th_args;
@ -89,7 +90,7 @@ main( int argc __attribute__((unused)),
if (ca_path!=0) if (ca_path!=0)
printf("CApath : %s\n", ca_path); 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 */ /* Prepare TCP socket for receiving connections */

View File

@ -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; int r=0;
DBUG_ENTER("vio_blocking"); DBUG_ENTER("vio_blocking");

View File

@ -118,8 +118,11 @@ int vio_ssl_read(Vio * vio, gptr buf, int size)
#endif /* DBUG_OFF */ #endif /* DBUG_OFF */
r = SSL_read(vio->ssl_, buf, size); r = SSL_read(vio->ssl_, buf, size);
#ifndef DBUG_OFF #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(); report_errors();
}
#endif /* DBUG_OFF */ #endif /* DBUG_OFF */
DBUG_PRINT("exit", ("%d", r)); DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(r); DBUG_RETURN(r);
@ -207,7 +210,6 @@ int vio_ssl_close(Vio * vio)
r = SSL_shutdown(vio->ssl_); r = SSL_shutdown(vio->ssl_);
SSL_free(vio->ssl_); SSL_free(vio->ssl_);
vio->ssl_= 0; vio->ssl_= 0;
vio->bio_ = 0;
} }
if (shutdown(vio->sd,2)) if (shutdown(vio->sd,2))
r= -1; r= -1;
@ -298,12 +300,11 @@ my_bool vio_ssl_poll_read(Vio *vio,uint timeout)
#endif #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; char *str;
int i; char buf[1024];
// const int blocking = vio_is_blocking(vio);
DBUG_ENTER("sslaccept"); DBUG_ENTER("sslaccept");
DBUG_PRINT("enter", ("sd=%d ptr=%p", vio->sd,ptr)); DBUG_PRINT("enter", ("sd=%d ptr=%p", vio->sd,ptr));
vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); 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_VOID_RETURN;
} }
DBUG_PRINT("info", ("ssl_=%p",vio->ssl_)); DBUG_PRINT("info", ("ssl_=%p",vio->ssl_));
SSL_clear(vio->ssl_);
vio_blocking(vio, FALSE); vio_blocking(vio, FALSE);
SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout);
SSL_set_fd(vio->ssl_,vio->sd); SSL_set_fd(vio->ssl_,vio->sd);
SSL_set_accept_state(vio->ssl_); SSL_set_accept_state(vio->ssl_);
SSL_do_handshake(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);
}
vio->open_ = TRUE; vio->open_ = TRUE;
#ifndef DBUF_OFF #ifndef DBUF_OFF
DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'" 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)); DBUG_PRINT("info",("\t issuer: %s", str));
free (str); free (str);
/* We could do all sorts of certificate verification stuff here before
* deallocating the certificate. */
X509_free (client_cert); X509_free (client_cert);
} else } else
DBUG_PRINT("info",("Client does not have certificate.")); 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 #endif
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio) void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout)
{ {
char *str; char *str;
// char s[]="abc";
int i;
X509* server_cert; X509* server_cert;
const int blocking = vio_is_blocking(vio);
DBUG_ENTER("sslconnect"); DBUG_ENTER("sslconnect");
DBUG_PRINT("enter", ("sd=%d ptr=%p ctx: %p", vio->sd,ptr,ptr->ssl_context_)); 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); vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE);
@ -403,50 +372,13 @@ int i;
report_errors(); report_errors();
DBUG_VOID_RETURN; 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); vio_blocking(vio, FALSE);
SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout);
SSL_set_fd (vio->ssl_, vio->sd); SSL_set_fd (vio->ssl_, vio->sd);
SSL_set_connect_state(vio->ssl_); SSL_set_connect_state(vio->ssl_);
SSL_do_handshake(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);
}
vio->open_ = TRUE; vio->open_ = TRUE;
#ifndef DBUG_OFF #ifndef DBUG_OFF
DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'" DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
@ -469,9 +401,7 @@ int i;
} else } else
DBUG_PRINT("info",("Server does not have certificate.")); DBUG_PRINT("info",("Server does not have certificate."));
#endif #endif
vio_blocking(vio, blocking);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */

View File

@ -168,15 +168,17 @@ vio_verify_callback(int ok, X509_STORE_CTX *ctx)
struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file, struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file,
const char* cert_file, const char* cert_file,
const char* ca_file, const char* ca_file,
const char* ca_path) const char* ca_path,
const char* cipher)
{ {
int verify = SSL_VERIFY_PEER; int verify = SSL_VERIFY_PEER;
struct st_VioSSLConnectorFd* ptr; struct st_VioSSLConnectorFd* ptr;
int result;
DH *dh=NULL; DH *dh=NULL;
DBUG_ENTER("new_VioSSLConnectorFd"); DBUG_ENTER("new_VioSSLConnectorFd");
DBUG_PRINT("enter", DBUG_PRINT("enter",
("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s", ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s",
key_file, cert_file, ca_path, ca_file)); key_file, cert_file, ca_path, ca_file, cipher));
ptr=(struct st_VioSSLConnectorFd*)my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0)); ptr=(struct st_VioSSLConnectorFd*)my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0));
ptr->ssl_context_=0; ptr->ssl_context_=0;
ptr->ssl_method_=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_options
* SSL_CTX_set_info_callback * 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); 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(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); SSL_CTX_set_tmp_dh(ptr->ssl_context_,dh);
DH_free(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); DBUG_RETURN(ptr);
ctor_failure: ctor_failure:
DBUG_PRINT("exit", ("there was an error")); DBUG_PRINT("exit", ("there was an error"));
@ -253,18 +251,20 @@ struct st_VioSSLAcceptorFd*
new_VioSSLAcceptorFd(const char* key_file, new_VioSSLAcceptorFd(const char* key_file,
const char* cert_file, const char* cert_file,
const char* ca_file, const char* ca_file,
const char* ca_path) const char* ca_path,
const char* cipher)
{ {
int verify = (SSL_VERIFY_PEER | int verify = (SSL_VERIFY_PEER |
SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
SSL_VERIFY_CLIENT_ONCE); SSL_VERIFY_CLIENT_ONCE);
struct st_VioSSLAcceptorFd* ptr; struct st_VioSSLAcceptorFd* ptr;
int result;
DH *dh=NULL; DH *dh=NULL;
DBUG_ENTER("new_VioSSLAcceptorFd"); DBUG_ENTER("new_VioSSLAcceptorFd");
DBUG_PRINT("enter", DBUG_PRINT("enter",
("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s", ("key_file=%s, cert_file=%s, ca_path=%s, ca_file=%s, cipher=%s",
key_file, cert_file, ca_path, ca_file)); key_file, cert_file, ca_path, ca_file, cipher));
ptr=(struct st_VioSSLAcceptorFd*)my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0)); ptr=(struct st_VioSSLAcceptorFd*)my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0));
ptr->ssl_context_=0; ptr->ssl_context_=0;
@ -293,12 +293,19 @@ new_VioSSLAcceptorFd(const char* key_file,
report_errors(); report_errors();
goto ctor_failure; 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_set_quiet_shutdown(ctx,1);
* *
*/ */
SSL_CTX_sess_set_cache_size(ptr->ssl_context_,128); SSL_CTX_sess_set_cache_size(ptr->ssl_context_,128);
/* DH? /* DH?
*/ */
SSL_CTX_set_verify(ptr->ssl_context_, verify, vio_verify_callback); 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); SSL_CTX_set_tmp_dh(ptr->ssl_context_,dh);
DH_free(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); DBUG_RETURN(ptr);
ctor_failure: ctor_failure:
DBUG_PRINT("exit", ("there was an error")); DBUG_PRINT("exit", ("there was an error"));