Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
aa3abd15
Commit
aa3abd15
authored
Mar 10, 2006
by
msvensson@neptunus.(none)
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup SSL implementation
Remove duplicate code Merge common functions Enforce MySQL coding standard
parent
1442be97
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
331 additions
and
484 deletions
+331
-484
include/violite.h
include/violite.h
+5
-16
sql-common/client.c
sql-common/client.c
+89
-17
sql/mysql_priv.h
sql/mysql_priv.h
+1
-1
sql/mysqld.cc
sql/mysqld.cc
+5
-2
sql/sql_acl.cc
sql/sql_acl.cc
+2
-2
vio/vio.c
vio/vio.c
+8
-8
vio/vio_priv.h
vio/vio_priv.h
+2
-20
vio/viossl.c
vio/viossl.c
+90
-246
vio/viosslfactories.c
vio/viosslfactories.c
+129
-172
No files found.
include/violite.h
View file @
aa3abd15
...
...
@@ -105,33 +105,22 @@ void vio_timeout(Vio *vio,uint which, uint timeout);
#include <openssl/ssl.h>
#include <openssl/err.h>
struct
st_VioSSL
AcceptorFd
struct
st_VioSSL
Fd
{
SSL_CTX
*
ssl_context
;
SSL_METHOD
*
ssl_method
;
struct
st_VioSSLAcceptorFd
*
session_id_context
;
};
/* One copy for client */
struct
st_VioSSLConnectorFd
{
SSL_CTX
*
ssl_context
;
/* function pointers which are only once for SSL client */
SSL_METHOD
*
ssl_method
;
};
int
sslaccept
(
struct
st_VioSSLAcceptorFd
*
,
Vio
*
,
long
timeout
);
int
sslconnect
(
struct
st_VioSSLConnectorFd
*
,
Vio
*
,
long
timeout
);
int
sslaccept
(
struct
st_VioSSLFd
*
,
Vio
*
,
long
timeout
);
int
sslconnect
(
struct
st_VioSSLFd
*
,
Vio
*
,
long
timeout
);
struct
st_VioSSL
Connector
Fd
struct
st_VioSSLFd
*
new_VioSSLConnectorFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
cipher
);
struct
st_VioSSL
Acceptor
Fd
struct
st_VioSSLFd
*
new_VioSSLAcceptorFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
cipher
);
Vio
*
new_VioSSL
(
struct
st_VioSSLAcceptorFd
*
fd
,
Vio
*
sd
,
int
state
);
#endif
/* HAVE_OPENSSL */
#ifdef HAVE_SMEM
...
...
sql-common/client.c
View file @
aa3abd15
...
...
@@ -1514,8 +1514,7 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
static
void
mysql_ssl_free
(
MYSQL
*
mysql
__attribute__
((
unused
)))
{
struct
st_VioSSLConnectorFd
*
st
=
(
struct
st_VioSSLConnectorFd
*
)
mysql
->
connector_fd
;
struct
st_VioSSLFd
*
ssl_fd
=
(
struct
st_VioSSLFd
*
)
mysql
->
connector_fd
;
DBUG_ENTER
(
"mysql_ssl_free"
);
my_free
(
mysql
->
options
.
ssl_key
,
MYF
(
MY_ALLOW_ZERO_PTR
));
...
...
@@ -1523,8 +1522,8 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
my_free
(
mysql
->
options
.
ssl_ca
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
(
mysql
->
options
.
ssl_capath
,
MYF
(
MY_ALLOW_ZERO_PTR
));
my_free
(
mysql
->
options
.
ssl_cipher
,
MYF
(
MY_ALLOW_ZERO_PTR
));
if
(
s
t
)
SSL_CTX_free
(
s
t
->
ssl_context
);
if
(
s
sl_fd
)
SSL_CTX_free
(
s
sl_fd
->
ssl_context
);
my_free
(
mysql
->
connector_fd
,
MYF
(
MY_ALLOW_ZERO_PTR
));
mysql
->
options
.
ssl_key
=
0
;
mysql
->
options
.
ssl_cert
=
0
;
...
...
@@ -1568,6 +1567,63 @@ static MYSQL_METHODS client_methods=
#endif
};
int
ssl_verify_server_cert
(
Vio
*
vio
,
const
char
*
server_host
)
{
SSL
*
ssl
;
X509
*
server_cert
;
char
*
cp1
,
*
cp2
;
char
buf
[
256
];
DBUG_ENTER
(
"ssl_verify_server_cert"
);
DBUG_PRINT
(
"enter"
,
(
"server_host: %s"
,
server_host
));
if
(
!
(
ssl
=
(
SSL
*
)
vio
->
ssl_arg
))
{
DBUG_PRINT
(
"error"
,
(
"No SSL pointer found"
));
return
1
;
}
if
(
!
server_host
)
{
DBUG_PRINT
(
"error"
,
(
"No server hostname supplied"
));
return
1
;
}
if
(
!
(
server_cert
=
SSL_get_peer_certificate
(
ssl
)))
{
DBUG_PRINT
(
"error"
,
(
"Could not get server certificate"
));
return
1
;
}
/*
We already know that the certificate exchanged was valid; the SSL library
handled that. Now we need to verify that the contents of the certificate
are what we expect.
*/
X509_NAME_oneline
(
X509_get_subject_name
(
server_cert
),
buf
,
sizeof
(
buf
));
X509_free
(
server_cert
);
// X509_NAME_get_text_by_NID(x509_get_subject_name(server_cert), NID_commonName, buf, sizeof(buf));... does the same thing
DBUG_PRINT
(
"info"
,
(
"hostname in cert: %s"
,
buf
));
cp1
=
strstr
(
buf
,
"/CN="
);
if
(
cp1
)
{
cp1
+=
4
;
// Skip the "/CN=" that we found
cp2
=
strchr
(
cp1
,
'/'
);
if
(
cp2
)
*
cp2
=
'\0'
;
DBUG_PRINT
(
"info"
,
(
"Server hostname in cert: "
,
cp1
));
if
(
!
strcmp
(
cp1
,
server_host
))
{
/* Success */
DBUG_RETURN
(
0
);
}
}
DBUG_PRINT
(
"error"
,
(
"SSL certificate validation failure"
));
DBUG_RETURN
(
1
);
}
MYSQL
*
CLI_MYSQL_REAL_CONNECT
(
MYSQL
*
mysql
,
const
char
*
host
,
const
char
*
user
,
...
...
@@ -2013,37 +2069,53 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
mysql
->
client_flag
=
client_flag
;
#ifdef HAVE_OPENSSL
/*
Oops.. are we careful enough to not send ANY information without
encryption?
*/
if
(
client_flag
&
CLIENT_SSL
)
{
/* Do the SSL layering. */
struct
st_mysql_options
*
options
=
&
mysql
->
options
;
struct
st_VioSSLFd
*
ssl_fd
;
/*
Send client_flag, max_packet_size - unencrypted otherwise
the server does not know we want to do SSL
*/
if
(
my_net_write
(
net
,
buff
,(
uint
)
(
end
-
buff
))
||
net_flush
(
net
))
{
set_mysql_error
(
mysql
,
CR_SERVER_LOST
,
unknown_sqlstate
);
goto
error
;
}
/* Do the SSL layering. */
if
(
!
(
mysql
->
connector_fd
=
(
gptr
)
new_VioSSLConnectorFd
(
options
->
ssl_key
,
options
->
ssl_cert
,
options
->
ssl_ca
,
options
->
ssl_capath
,
options
->
ssl_cipher
)))
/* Create the VioSSLConnectorFd - init SSL and load certs */
if
(
!
(
ssl_fd
=
new_VioSSLConnectorFd
(
options
->
ssl_key
,
options
->
ssl_cert
,
options
->
ssl_ca
,
options
->
ssl_capath
,
options
->
ssl_cipher
)))
{
set_mysql_error
(
mysql
,
CR_SSL_CONNECTION_ERROR
,
unknown_sqlstate
);
goto
error
;
}
mysql
->
connector_fd
=
(
void
*
)
ssl_fd
;
/* Connect to the server */
DBUG_PRINT
(
"info"
,
(
"IO layer change in progress..."
));
if
(
sslconnect
(
(
struct
st_VioSSLConnectorFd
*
)(
mysql
->
connector_fd
)
,
mysql
->
net
.
vio
,
(
long
)
(
mysql
->
options
.
connect_timeout
)))
if
(
sslconnect
(
ssl_fd
,
mysql
->
net
.
vio
,
(
long
)
(
mysql
->
options
.
connect_timeout
)))
{
set_mysql_error
(
mysql
,
CR_SSL_CONNECTION_ERROR
,
unknown_sqlstate
);
goto
error
;
}
DBUG_PRINT
(
"info"
,
(
"IO layer change done!"
));
#if 0
/* Verify server cert */
if (mysql->options.ssl_verify_cert &&
ssl_verify_server_cert(mysql->net.vio, mysql->host))
{
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
goto error;
}
#endif
}
#endif
/* HAVE_OPENSSL */
...
...
sql/mysql_priv.h
View file @
aa3abd15
...
...
@@ -1258,7 +1258,7 @@ extern pthread_t signal_thread;
#endif
#ifdef HAVE_OPENSSL
extern
struct
st_VioSSL
Acceptor
Fd
*
ssl_acceptor_fd
;
extern
struct
st_VioSSLFd
*
ssl_acceptor_fd
;
#endif
/* HAVE_OPENSSL */
MYSQL_LOCK
*
mysql_lock_tables
(
THD
*
thd
,
TABLE
**
table
,
uint
count
,
...
...
sql/mysqld.cc
View file @
aa3abd15
...
...
@@ -599,7 +599,7 @@ static void openssl_lock(int, openssl_lock_t *, const char *, int);
static
unsigned
long
openssl_id_function
();
#endif
char
*
des_key_file
;
struct
st_VioSSL
Acceptor
Fd
*
ssl_acceptor_fd
;
struct
st_VioSSLFd
*
ssl_acceptor_fd
;
#endif
/* HAVE_OPENSSL */
...
...
@@ -1110,7 +1110,10 @@ void clean_up(bool print_message)
#endif
#ifdef HAVE_OPENSSL
if
(
ssl_acceptor_fd
)
my_free
((
gptr
)
ssl_acceptor_fd
,
MYF
(
MY_ALLOW_ZERO_PTR
));
{
SSL_CTX_free
(
ssl_acceptor_fd
->
ssl_context
);
my_free
((
gptr
)
ssl_acceptor_fd
,
MYF
(
0
));
}
#endif
/* HAVE_OPENSSL */
#ifdef USE_REGEX
my_regex_end
();
...
...
sql/sql_acl.cc
View file @
aa3abd15
...
...
@@ -858,8 +858,8 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
if
(
acl_user
->
x509_issuer
)
{
DBUG_PRINT
(
"info"
,(
"checkpoint 3"
));
char
*
ptr
=
X509_NAME_oneline
(
X509_get_issuer_name
(
cert
),
0
,
0
);
DBUG_PRINT
(
"info"
,(
"comparing issuers: '%s' and '%s'"
,
char
*
ptr
=
X509_NAME_oneline
(
X509_get_issuer_name
(
cert
),
0
,
0
);
DBUG_PRINT
(
"info"
,(
"comparing issuers: '%s' and '%s'"
,
acl_user
->
x509_issuer
,
ptr
));
if
(
strcmp
(
acl_user
->
x509_issuer
,
ptr
))
{
...
...
vio/vio.c
View file @
aa3abd15
...
...
@@ -88,19 +88,19 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
if
(
type
==
VIO_TYPE_SSL
)
{
vio
->
viodelete
=
vio_delete
;
vio
->
vioerrno
=
vio_
ssl_
errno
;
vio
->
vioerrno
=
vio_errno
;
vio
->
read
=
vio_ssl_read
;
vio
->
write
=
vio_ssl_write
;
vio
->
fastsend
=
vio_
ssl_
fastsend
;
vio
->
viokeepalive
=
vio_
ssl_
keepalive
;
vio
->
should_retry
=
vio_s
sl_s
hould_retry
;
vio
->
was_interrupted
=
vio_
ssl_
was_interrupted
;
vio
->
fastsend
=
vio_fastsend
;
vio
->
viokeepalive
=
vio_keepalive
;
vio
->
should_retry
=
vio_should_retry
;
vio
->
was_interrupted
=
vio_was_interrupted
;
vio
->
vioclose
=
vio_ssl_close
;
vio
->
peer_addr
=
vio_
ssl_
peer_addr
;
vio
->
in_addr
=
vio_
ssl_
in_addr
;
vio
->
peer_addr
=
vio_peer_addr
;
vio
->
in_addr
=
vio_in_addr
;
vio
->
vioblocking
=
vio_ssl_blocking
;
vio
->
is_blocking
=
vio_is_blocking
;
vio
->
timeout
=
vio_
ssl_
timeout
;
vio
->
timeout
=
vio_timeout
;
}
else
/* default is VIO_TYPE_TCPIP */
#endif
/* HAVE_OPENSSL */
...
...
vio/vio_priv.h
View file @
aa3abd15
...
...
@@ -30,28 +30,10 @@ void vio_ignore_timeout(Vio *vio, uint which, uint timeout);
int
vio_ssl_read
(
Vio
*
vio
,
gptr
buf
,
int
size
);
int
vio_ssl_write
(
Vio
*
vio
,
const
gptr
buf
,
int
size
);
void
vio_ssl_timeout
(
Vio
*
vio
,
uint
which
,
uint
timeout
);
/* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. */
int
vio_ssl_fastsend
(
Vio
*
vio
);
/* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible. */
int
vio_ssl_keepalive
(
Vio
*
vio
,
my_bool
onoff
);
/* Whenever we should retry the last read/write operation. */
my_bool
vio_ssl_should_retry
(
Vio
*
vio
);
/* Check that operation was timed out */
my_bool
vio_ssl_was_interrupted
(
Vio
*
vio
);
/* When the workday is over... */
int
vio_ssl_close
(
Vio
*
vio
);
/* Return last error number */
int
vio_ssl_errno
(
Vio
*
vio
);
my_bool
vio_ssl_peer_addr
(
Vio
*
vio
,
char
*
buf
,
uint16
*
port
);
void
vio_ssl_in_addr
(
Vio
*
vio
,
struct
in_addr
*
in
);
int
vio_ssl_blocking
(
Vio
*
vio
,
my_bool
set_blocking_mode
,
my_bool
*
old_mode
);
/* Single copy for server */
enum
vio_ssl_acceptorfd_state
{
state_connect
=
1
,
state_accept
=
2
};
#endif
/* HAVE_OPENSSL */
vio/viossl.c
View file @
aa3abd15
...
...
@@ -70,12 +70,6 @@ report_errors()
}
int
vio_ssl_errno
(
Vio
*
vio
__attribute__
((
unused
)))
{
return
socket_errno
;
/* On Win32 this mapped to WSAGetLastError() */
}
int
vio_ssl_read
(
Vio
*
vio
,
gptr
buf
,
int
size
)
{
int
r
;
...
...
@@ -107,183 +101,51 @@ int vio_ssl_write(Vio * vio, const gptr buf, int size)
}
int
vio_ssl_fastsend
(
Vio
*
vio
__attribute__
((
unused
)))
{
int
r
=
0
;
DBUG_ENTER
(
"vio_ssl_fastsend"
);
#if defined(IPTOS_THROUGHPUT) && !defined(__EMX__)
{
int
tos
=
IPTOS_THROUGHPUT
;
r
=
setsockopt
(
vio
->
sd
,
IPPROTO_IP
,
IP_TOS
,
(
void
*
)
&
tos
,
sizeof
(
tos
));
}
#endif
/* IPTOS_THROUGHPUT && !__EMX__ */
if
(
!
r
)
{
#ifdef __WIN__
BOOL
nodelay
=
1
;
r
=
setsockopt
(
vio
->
sd
,
IPPROTO_TCP
,
TCP_NODELAY
,
(
const
char
*
)
&
nodelay
,
sizeof
(
nodelay
));
#else
int
nodelay
=
1
;
r
=
setsockopt
(
vio
->
sd
,
IPPROTO_TCP
,
TCP_NODELAY
,
(
void
*
)
&
nodelay
,
sizeof
(
nodelay
));
#endif
/* __WIN__ */
}
if
(
r
)
{
DBUG_PRINT
(
"warning"
,
(
"Couldn't set socket option for fast send"
));
r
=
-
1
;
}
DBUG_PRINT
(
"exit"
,
(
"%d"
,
r
));
DBUG_RETURN
(
r
);
}
int
vio_ssl_keepalive
(
Vio
*
vio
,
my_bool
set_keep_alive
)
{
int
r
=
0
;
DBUG_ENTER
(
"vio_ssl_keepalive"
);
DBUG_PRINT
(
"enter"
,
(
"sd: %d, set_keep_alive: %d"
,
vio
->
sd
,
(
int
)
set_keep_alive
));
if
(
vio
->
type
!=
VIO_TYPE_NAMEDPIPE
)
{
uint
opt
=
(
set_keep_alive
)
?
1
:
0
;
r
=
setsockopt
(
vio
->
sd
,
SOL_SOCKET
,
SO_KEEPALIVE
,
(
char
*
)
&
opt
,
sizeof
(
opt
));
}
DBUG_RETURN
(
r
);
}
my_bool
vio_ssl_should_retry
(
Vio
*
vio
__attribute__
((
unused
)))
{
int
en
=
socket_errno
;
return
(
en
==
SOCKET_EAGAIN
||
en
==
SOCKET_EINTR
||
en
==
SOCKET_EWOULDBLOCK
);
}
my_bool
vio_ssl_was_interrupted
(
Vio
*
vio
__attribute__
((
unused
)))
{
int
en
=
socket_errno
;
return
(
en
==
SOCKET_EAGAIN
||
en
==
SOCKET_EINTR
||
en
==
SOCKET_EWOULDBLOCK
||
en
==
SOCKET_ETIMEDOUT
);
}
int
vio_ssl_close
(
Vio
*
vio
)
{
int
r
;
int
r
=
0
;
SSL
*
ssl
=
(
SSL
*
)
vio
->
ssl_arg
;
DBUG_ENTER
(
"vio_ssl_close"
);
r
=
0
;
if
((
SSL
*
)
vio
->
ssl_arg
)
{
r
=
SSL_shutdown
((
SSL
*
)
vio
->
ssl_arg
);
SSL_free
((
SSL
*
)
vio
->
ssl_arg
);
vio
->
ssl_arg
=
0
;
}
if
(
vio
->
sd
>=
0
)
{
if
(
shutdown
(
vio
->
sd
,
2
))
r
=
-
1
;
if
(
closesocket
(
vio
->
sd
))
r
=
-
1
;
}
if
(
r
)
{
DBUG_PRINT
(
"error"
,
(
"close() failed, error: %d"
,
socket_errno
));
report_errors
();
/* FIXME: error handling (not critical for MySQL) */
}
vio
->
type
=
VIO_CLOSED
;
vio
->
sd
=
-
1
;
DBUG_RETURN
(
r
);
}
const
char
*
vio_ssl_description
(
Vio
*
vio
)
{
return
vio
->
desc
;
}
enum
enum_vio_type
vio_ssl_type
(
Vio
*
vio
)
{
return
vio
->
type
;
}
my_socket
vio_ssl_fd
(
Vio
*
vio
)
{
return
vio
->
sd
;
}
my_bool
vio_ssl_peer_addr
(
Vio
*
vio
,
char
*
buf
,
uint16
*
port
)
{
DBUG_ENTER
(
"vio_ssl_peer_addr"
);
DBUG_PRINT
(
"enter"
,
(
"sd: %d"
,
vio
->
sd
));
if
(
vio
->
localhost
)
{
strmov
(
buf
,
"127.0.0.1"
);
*
port
=
0
;
}
else
if
(
ssl
)
{
size_socket
addrLen
=
sizeof
(
struct
sockaddr
);
if
(
getpeername
(
vio
->
sd
,
(
struct
sockaddr
*
)
(
&
(
vio
->
remote
)),
&
addrLen
)
!=
0
)
switch
((
r
=
SSL_shutdown
(
ssl
)))
{
DBUG_PRINT
(
"exit"
,
(
"getpeername, error: %d"
,
socket_errno
));
DBUG_RETURN
(
1
);
case
1
:
/* Shutdown successful */
break
;
case
0
:
/* Shutdown not yet finished, call it again */
if
((
r
=
SSL_shutdown
(
ssl
)
>=
0
))
break
;
/* Fallthrough */
default:
/* Shutdown failed */
DBUG_PRINT
(
"vio_error"
,
(
"SSL_shutdown() failed, error: %s"
,
SSL_get_error
(
ssl
,
r
)));
break
;
}
#ifdef TO_BE_FIXED
my_inet_ntoa
(
vio
->
remote
.
sin_addr
,
buf
);
*
port
=
0
;
#else
strmov
(
buf
,
"unknown"
);
*
port
=
0
;
#endif
SSL_free
(
ssl
);
vio
->
ssl_arg
=
0
;
}
DBUG_PRINT
(
"exit"
,
(
"addr: %s"
,
buf
));
DBUG_RETURN
(
0
);
}
void
vio_ssl_in_addr
(
Vio
*
vio
,
struct
in_addr
*
in
)
{
DBUG_ENTER
(
"vio_ssl_in_addr"
);
if
(
vio
->
localhost
)
bzero
((
char
*
)
in
,
sizeof
(
*
in
));
else
*
in
=
vio
->
remote
.
sin_addr
;
DBUG_VOID_RETURN
;
DBUG_RETURN
(
vio_close
(
vio
));
}
/*
TODO: Add documentation
*/
int
sslaccept
(
struct
st_VioSSLAcceptorFd
*
ptr
,
Vio
*
vio
,
long
timeout
)
int
sslaccept
(
struct
st_VioSSLFd
*
ptr
,
Vio
*
vio
,
long
timeout
)
{
char
*
str
;
char
buf
[
1024
];
SSL
*
ssl
;
X509
*
client_cert
;
my_bool
unused
;
my_bool
net_blocking
;
enum
enum_vio_type
old_type
;
DBUG_ENTER
(
"sslaccept"
);
DBUG_PRINT
(
"enter"
,
(
"sd: %d ptr:
Ox
%p, timeout: %d"
,
DBUG_PRINT
(
"enter"
,
(
"sd: %d ptr: %p, timeout: %d"
,
vio
->
sd
,
ptr
,
timeout
));
old_type
=
vio
->
type
;
net_blocking
=
vio_is_blocking
(
vio
);
net_blocking
=
vio_is_blocking
(
vio
);
vio_blocking
(
vio
,
1
,
&
unused
);
/* Must be called before reset */
vio_reset
(
vio
,
VIO_TYPE_SSL
,
vio
->
sd
,
0
,
FALSE
);
vio
->
ssl_arg
=
0
;
if
(
!
(
vio
->
ssl_arg
=
(
void
*
)
SSL_new
(
ptr
->
ssl_context
)))
vio_reset
(
vio
,
VIO_TYPE_SSL
,
vio
->
sd
,
0
,
FALSE
);
if
(
!
(
ssl
=
SSL_new
(
ptr
->
ssl_context
)))
{
DBUG_PRINT
(
"error"
,
(
"SSL_new failure"
));
report_errors
();
...
...
@@ -291,121 +153,114 @@ int sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout)
vio_blocking
(
vio
,
net_blocking
,
&
unused
);
DBUG_RETURN
(
1
);
}
DBUG_PRINT
(
"info"
,
(
"ssl_: Ox%p timeout: %ld"
,
(
SSL
*
)
vio
->
ssl_arg
,
timeout
));
SSL_clear
(
(
SSL
*
)
vio
->
ssl_arg
);
SSL_SESSION_set_timeout
(
SSL_get_session
(
(
SSL
*
)
vio
->
ssl_arg
),
timeout
);
SSL_set_fd
(
(
SSL
*
)
vio
->
ssl_arg
,
vio
->
sd
);
SSL_set_accept_state
(
(
SSL
*
)
vio
->
ssl_arg
);
if
(
SSL_do_handshake
(
(
SSL
*
)
vio
->
ssl_arg
)
<
1
)
vio
->
ssl_arg
=
(
void
*
)
ssl
;
DBUG_PRINT
(
"info"
,
(
"ssl_: %p timeout: %ld"
,
ssl
,
timeout
));
SSL_clear
(
ssl
);
SSL_SESSION_set_timeout
(
SSL_get_session
(
ssl
),
timeout
);
SSL_set_fd
(
ssl
,
vio
->
sd
);
SSL_set_accept_state
(
ssl
);
if
(
SSL_do_handshake
(
ssl
)
<
1
)
{
DBUG_PRINT
(
"error"
,
(
"SSL_do_handshake failure"
));
report_errors
();
SSL_free
(
(
SSL
*
)
vio
->
ssl_arg
);
SSL_free
(
ssl
);
vio
->
ssl_arg
=
0
;
vio_reset
(
vio
,
old_type
,
vio
->
sd
,
0
,
FALSE
);
vio_blocking
(
vio
,
net_blocking
,
&
unused
);
DBUG_RETURN
(
1
);
}
#ifndef DBUG_OFF
DBUG_PRINT
(
"info"
,(
"SSL_get_cipher_name() = '%s'"
,
SSL_get_cipher_name
((
SSL
*
)
vio
->
ssl_arg
)));
client_cert
=
SSL_get_peer_certificate
((
SSL
*
)
vio
->
ssl_arg
);
if
(
client_cert
!=
NULL
)
{
DBUG_PRINT
(
"info"
,(
"Client certificate:"
));
str
=
X509_NAME_oneline
(
X509_get_subject_name
(
client_cert
),
0
,
0
);
DBUG_PRINT
(
"info"
,(
"
\t
subject: %s"
,
str
));
free
(
str
);
char
buf
[
1024
];
DBUG_PRINT
(
"info"
,(
"cipher_name= '%s'"
,
SSL_get_cipher_name
(
ssl
)));
str
=
X509_NAME_oneline
(
X509_get_issuer_name
(
client_cert
),
0
,
0
);
DBUG_PRINT
(
"info"
,(
"
\t
issuer: %s"
,
str
));
free
(
str
);
if
((
client_cert
=
SSL_get_peer_certificate
(
ssl
)))
{
DBUG_PRINT
(
"info"
,(
"Client certificate:"
));
X509_NAME_oneline
(
X509_get_subject_name
(
client_cert
),
buf
,
sizeof
(
buf
));
DBUG_PRINT
(
"info"
,(
"
\t
subject: %s"
,
buf
));
X509_free
(
client_cert
);
}
else
DBUG_PRINT
(
"info"
,(
"Client does not have certificate."
));
X509_NAME_oneline
(
X509_get_issuer_name
(
client_cert
),
buf
,
sizeof
(
buf
));
DBUG_PRINT
(
"info"
,(
"
\t
issuer: %s"
,
buf
));
str
=
SSL_get_shared_ciphers
((
SSL
*
)
vio
->
ssl_arg
,
buf
,
sizeof
(
buf
));
if
(
str
)
{
DBUG_PRINT
(
"info"
,(
"SSL_get_shared_ciphers() returned '%s'"
,
str
));
}
else
{
DBUG_PRINT
(
"info"
,(
"no shared ciphers!"
));
}
X509_free
(
client_cert
);
}
else
DBUG_PRINT
(
"info"
,(
"Client does not have certificate."
));
if
(
SSL_get_shared_ciphers
(
ssl
,
buf
,
sizeof
(
buf
)))
{
DBUG_PRINT
(
"info"
,(
"shared_ciphers: '%s'"
,
buf
));
}
else
DBUG_PRINT
(
"info"
,(
"no shared ciphers!"
));
}
#endif
DBUG_RETURN
(
0
);
}
int
sslconnect
(
struct
st_VioSSL
Connector
Fd
*
ptr
,
Vio
*
vio
,
long
timeout
)
int
sslconnect
(
struct
st_VioSSLFd
*
ptr
,
Vio
*
vio
,
long
timeout
)
{
char
*
str
;
X509
*
server_cert
;
SSL
*
ssl
;
X509
*
server_cert
;
my_bool
unused
;
my_bool
net_blocking
;
enum
enum_vio_type
old_type
;
enum
enum_vio_type
old_type
;
DBUG_ENTER
(
"sslconnect"
);
DBUG_PRINT
(
"enter"
,
(
"sd: %d
ptr: 0x%p ctx: 0x
%p"
,
vio
->
sd
,
ptr
,
ptr
->
ssl_context
));
DBUG_PRINT
(
"enter"
,
(
"sd: %d
, ptr: %p, ctx:
%p"
,
vio
->
sd
,
ptr
,
ptr
->
ssl_context
));
old_type
=
vio
->
type
;
net_blocking
=
vio_is_blocking
(
vio
);
net_blocking
=
vio_is_blocking
(
vio
);
vio_blocking
(
vio
,
1
,
&
unused
);
/* Must be called before reset */
vio_reset
(
vio
,
VIO_TYPE_SSL
,
vio
->
sd
,
0
,
FALSE
);
vio
->
ssl_arg
=
0
;
if
(
!
(
vio
->
ssl_arg
=
SSL_new
(
ptr
->
ssl_context
)))
vio_reset
(
vio
,
VIO_TYPE_SSL
,
vio
->
sd
,
0
,
FALSE
);
if
(
!
(
ssl
=
SSL_new
(
ptr
->
ssl_context
)))
{
DBUG_PRINT
(
"error"
,
(
"SSL_new failure"
));
report_errors
();
vio_reset
(
vio
,
old_type
,
vio
->
sd
,
0
,
FALSE
);
vio_blocking
(
vio
,
net_blocking
,
&
unused
);
vio_reset
(
vio
,
old_type
,
vio
->
sd
,
0
,
FALSE
);
vio_blocking
(
vio
,
net_blocking
,
&
unused
);
DBUG_RETURN
(
1
);
}
DBUG_PRINT
(
"info"
,
(
"ssl_: 0x%p timeout: %ld"
,
(
SSL
*
)
vio
->
ssl_arg
,
timeout
));
SSL_clear
(
(
SSL
*
)
vio
->
ssl_arg
);
SSL_SESSION_set_timeout
(
SSL_get_session
(
(
SSL
*
)
vio
->
ssl_arg
),
timeout
);
SSL_set_fd
((
SSL
*
)
vio
->
ssl_arg
,
vio_ssl_fd
(
vio
)
);
SSL_set_connect_state
(
(
SSL
*
)
vio
->
ssl_arg
);
if
(
SSL_do_handshake
(
(
SSL
*
)
vio
->
ssl_arg
)
<
1
)
vio
->
ssl_arg
=
(
void
*
)
ssl
;
DBUG_PRINT
(
"info"
,
(
"ssl: %p, timeout: %ld"
,
ssl
,
timeout
));
SSL_clear
(
ssl
);
SSL_SESSION_set_timeout
(
SSL_get_session
(
ssl
),
timeout
);
SSL_set_fd
(
ssl
,
vio
->
sd
);
SSL_set_connect_state
(
ssl
);
if
(
SSL_do_handshake
(
ssl
)
<
1
)
{
DBUG_PRINT
(
"error"
,
(
"SSL_do_handshake failure"
));
report_errors
();
SSL_free
(
(
SSL
*
)
vio
->
ssl_arg
);
SSL_free
(
ssl
);
vio
->
ssl_arg
=
0
;
vio_reset
(
vio
,
old_type
,
vio
->
sd
,
0
,
FALSE
);
vio_reset
(
vio
,
old_type
,
vio
->
sd
,
0
,
FALSE
);
vio_blocking
(
vio
,
net_blocking
,
&
unused
);
DBUG_RETURN
(
1
);
}
}
#ifndef DBUG_OFF
DBUG_PRINT
(
"info"
,(
"SSL_get_cipher_name() = '%s'"
,
SSL_get_cipher_name
((
SSL
*
)
vio
->
ssl_arg
)));
server_cert
=
SSL_get_peer_certificate
((
SSL
*
)
vio
->
ssl_arg
);
if
(
server_cert
!=
NULL
)
DBUG_PRINT
(
"info"
,(
"cipher_name: '%s'"
,
SSL_get_cipher_name
(
ssl
)));
if
((
server_cert
=
SSL_get_peer_certificate
(
ssl
)))
{
char
buf
[
256
];
DBUG_PRINT
(
"info"
,(
"Server certificate:"
));
str
=
X509_NAME_oneline
(
X509_get_subject_name
(
server_cert
),
0
,
0
);
DBUG_PRINT
(
"info"
,(
"
\t
subject: %s"
,
str
));
free
(
str
);
str
=
X509_NAME_oneline
(
X509_get_issuer_name
(
server_cert
),
0
,
0
);
DBUG_PRINT
(
"info"
,(
"
\t
issuer: %s"
,
str
));
free
(
str
);
/*
We could do all sorts of certificate verification stuff here before
deallocating the certificate.
*/
X509_NAME_oneline
(
X509_get_subject_name
(
server_cert
),
buf
,
sizeof
(
buf
));
DBUG_PRINT
(
"info"
,(
"
\t
subject: %s"
,
buf
));
X509_NAME_oneline
(
X509_get_issuer_name
(
server_cert
),
buf
,
sizeof
(
buf
));
DBUG_PRINT
(
"info"
,(
"
\t
issuer: %s"
,
buf
));
X509_free
(
server_cert
);
}
else
DBUG_PRINT
(
"info"
,(
"Server does not have certificate."
));
#endif
DBUG_RETURN
(
0
);
}
...
...
@@ -414,21 +269,10 @@ int vio_ssl_blocking(Vio * vio __attribute__((unused)),
my_bool
set_blocking_mode
,
my_bool
*
old_mode
)
{
/* Mode is always blocking */
*
old_mode
=
1
;
/* Return error if we try to change to non_blocking mode */
*
old_mode
=
1
;
/* Mode is always blocking */
return
set_blocking_mode
?
0
:
1
;
return
(
set_blocking_mode
?
0
:
1
);
}
void
vio_ssl_timeout
(
Vio
*
vio
__attribute__
((
unused
)),
uint
which
__attribute__
((
unused
)),
uint
timeout
__attribute__
((
unused
)))
{
#ifdef __WIN__
ulong
wait_timeout
=
(
ulong
)
timeout
*
1000
;
(
void
)
setsockopt
(
vio
->
sd
,
SOL_SOCKET
,
which
?
SO_SNDTIMEO
:
SO_RCVTIMEO
,
(
char
*
)
&
wait_timeout
,
sizeof
(
wait_timeout
));
#endif
/* __WIN__ */
}
#endif
/* HAVE_OPENSSL */
vio/viosslfactories.c
View file @
aa3abd15
...
...
@@ -21,7 +21,6 @@
static
bool
ssl_algorithms_added
=
FALSE
;
static
bool
ssl_error_strings_loaded
=
FALSE
;
static
int
verify_depth
=
0
;
static
int
verify_error
=
X509_V_OK
;
static
unsigned
char
dh512_p
[]
=
{
...
...
@@ -82,30 +81,31 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
DBUG_ENTER
(
"vio_set_cert_stuff"
);
DBUG_PRINT
(
"enter"
,
(
"ctx: %p, cert_file: %s, key_file: %s"
,
ctx
,
cert_file
,
key_file
));
if
(
cert_file
!=
NULL
)
if
(
cert_file
)
{
if
(
SSL_CTX_use_certificate_file
(
ctx
,
cert_file
,
SSL_FILETYPE_PEM
)
<=
0
)
if
(
SSL_CTX_use_certificate_file
(
ctx
,
cert_file
,
SSL_FILETYPE_PEM
)
<=
0
)
{
DBUG_PRINT
(
"error"
,(
"unable to get certificate from '%s'
\n
"
,
cert_file
));
DBUG_PRINT
(
"error"
,(
"unable to get certificate from '%s'
\n
"
,
cert_file
));
/* FIX stderr */
fprintf
(
stderr
,
"Error when connection to server using SSL:"
);
ERR_print_errors_fp
(
stderr
);
fprintf
(
stderr
,
"Unable to get certificate from '%s'
\n
"
,
cert_file
);
fflush
(
stderr
);
DBUG_RETURN
(
0
);
DBUG_RETURN
(
1
);
}
if
(
key_file
==
NULL
)
key_file
=
cert_file
;
if
(
SSL_CTX_use_PrivateKey_file
(
ctx
,
key_file
,
SSL_FILETYPE_PEM
)
<=
0
)
if
(
!
key_file
)
key_file
=
cert_file
;
if
(
SSL_CTX_use_PrivateKey_file
(
ctx
,
key_file
,
SSL_FILETYPE_PEM
)
<=
0
)
{
DBUG_PRINT
(
"error"
,
(
"unable to get private key from '%s'
\n
"
,
key_file
));
DBUG_PRINT
(
"error"
,
(
"unable to get private key from '%s'
\n
"
,
key_file
));
/* FIX stderr */
fprintf
(
stderr
,
"Error when connection to server using SSL:"
);
ERR_print_errors_fp
(
stderr
);
fprintf
(
stderr
,
"Unable to get private key from '%s'
\n
"
,
cert_file
);
fflush
(
stderr
);
DBUG_RETURN
(
0
);
fflush
(
stderr
);
DBUG_RETURN
(
1
);
}
/*
...
...
@@ -116,45 +116,45 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
{
DBUG_PRINT
(
"error"
,
(
"Private key does not match the certificate public key
\n
"
));
DBUG_RETURN
(
0
);
DBUG_RETURN
(
1
);
}
}
DBUG_RETURN
(
1
);
DBUG_RETURN
(
0
);
}
static
int
vio_verify_callback
(
int
ok
,
X509_STORE_CTX
*
ctx
)
{
char
buf
[
256
];
X509
*
err_cert
;
int
err
,
depth
;
char
buf
[
256
];
X509
*
err_cert
;
DBUG_ENTER
(
"vio_verify_callback"
);
DBUG_PRINT
(
"enter"
,
(
"ok: %d, ctx: 0x%p"
,
ok
,
ctx
));
err_cert
=
X509_STORE_CTX_get_current_cert
(
ctx
);
err
=
X509_STORE_CTX_get_error
(
ctx
);
depth
=
X509_STORE_CTX_get_error_depth
(
ctx
);
DBUG_PRINT
(
"enter"
,
(
"ok: %d, ctx: %p"
,
ok
,
ctx
));
X509_NAME_oneline
(
X509_get_subject_name
(
err_cert
),
buf
,
sizeof
(
buf
));
err_cert
=
X509_STORE_CTX_get_current_cert
(
ctx
);
X509_NAME_oneline
(
X509_get_subject_name
(
err_cert
),
buf
,
sizeof
(
buf
));
DBUG_PRINT
(
"info"
,
(
"cert: %s"
,
buf
));
if
(
!
ok
)
{
DBUG_PRINT
(
"error"
,(
"verify error: num: %d : '%s'
\n
"
,
err
,
int
err
,
depth
;
err
=
X509_STORE_CTX_get_error
(
ctx
);
depth
=
X509_STORE_CTX_get_error_depth
(
ctx
);
DBUG_PRINT
(
"error"
,(
"verify error: %d, '%s'"
,
err
,
X509_verify_cert_error_string
(
err
)));
/*
Approve cert if depth is greater then "verify_depth", currently
verify_depth is always 0 and there is no way to increase it.
*/
if
(
verify_depth
>=
depth
)
{
ok
=
1
;
verify_error
=
X509_V_OK
;
}
else
{
verify_error
=
X509_V_ERR_CERT_CHAIN_TOO_LONG
;
}
ok
=
1
;
}
switch
(
ctx
->
error
)
{
switch
(
ctx
->
error
)
{
case
X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
:
X509_NAME_oneline
(
X509_get_issuer_name
(
ctx
->
current_cert
),
buf
,
256
);
DBUG_PRINT
(
"info"
,(
"issuer= %s
\n
"
,
buf
));
X509_NAME_oneline
(
X509_get_issuer_name
(
ctx
->
current_cert
),
buf
,
256
);
DBUG_PRINT
(
"info"
,(
"issuer= %s
\n
"
,
buf
));
break
;
case
X509_V_ERR_CERT_NOT_YET_VALID
:
case
X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD
:
...
...
@@ -198,193 +198,150 @@ static void netware_ssl_init()
#endif
/* __NETWARE__ */
/************************ VioSSLConnectorFd **********************************/
/*
TODO:
Add option --verify to mysql to be able to change verification mode
*/
struct
st_VioSSLConnectorFd
*
new_VioSSLConnectorFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
cipher
)
static
void
check_ssl_init
()
{
int
verify
=
SSL_VERIFY_NONE
;
struct
st_VioSSLConnectorFd
*
ptr
;
int
result
;
DH
*
dh
;
DBUG_ENTER
(
"new_VioSSLConnectorFd"
);
if
(
!
(
ptr
=
((
struct
st_VioSSLConnectorFd
*
)
my_malloc
(
sizeof
(
struct
st_VioSSLConnectorFd
),
MYF
(
0
)))))
DBUG_RETURN
(
0
);
ptr
->
ssl_context
=
0
;
ptr
->
ssl_method
=
0
;
/* FIXME: constants! */
if
(
!
ssl_algorithms_added
)
{
DBUG_PRINT
(
"info"
,
(
"todo: OpenSSL_add_all_algorithms()"
));
ssl_algorithms_added
=
TRUE
;
ssl_algorithms_added
=
TRUE
;
SSL_library_init
();
OpenSSL_add_all_algorithms
();
}
#ifdef __NETWARE__
/* MASV, should it be done everytime? */
netware_ssl_init
();
#endif
if
(
!
ssl_error_strings_loaded
)
{
DBUG_PRINT
(
"info"
,
(
"todo:SSL_load_error_strings()"
));
ssl_error_strings_loaded
=
TRUE
;
ssl_error_strings_loaded
=
TRUE
;
SSL_load_error_strings
();
}
ptr
->
ssl_method
=
TLSv1_client_method
();
ptr
->
ssl_context
=
SSL_CTX_new
(
ptr
->
ssl_method
);
DBUG_PRINT
(
"info"
,
(
"ssl_context: %p"
,
ptr
->
ssl_context
));
if
(
ptr
->
ssl_context
==
0
)
}
/************************ VioSSLFd **********************************/
struct
st_VioSSLFd
*
new_VioSSLFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
cipher
,
SSL_METHOD
*
method
)
{
DH
*
dh
;
struct
st_VioSSLFd
*
ssl_fd
;
DBUG_ENTER
(
"new_VioSSLFd"
);
check_ssl_init
();
if
(
!
(
ssl_fd
=
((
struct
st_VioSSLFd
*
)
my_malloc
(
sizeof
(
struct
st_VioSSLFd
),
MYF
(
0
)))))
DBUG_RETURN
(
0
);
if
(
!
(
ssl_fd
->
ssl_context
=
SSL_CTX_new
(
method
)))
{
DBUG_PRINT
(
"error"
,
(
"SSL_CTX_new failed"
));
report_errors
();
goto
ctor_failure
;
my_free
((
void
*
)
ssl_fd
,
MYF
(
0
));
DBUG_RETURN
(
0
);
}
/*
SSL_CTX_set_options
SSL_CTX_set_info_callback
*/
if
(
cipher
)
/* Set the ciphers that can be used */
if
(
cipher
&&
SSL_CTX_set_cipher_list
(
ssl_fd
->
ssl_context
,
cipher
))
{
result
=
SSL_CTX_set_cipher_list
(
ptr
->
ssl_context
,
cipher
);
DBUG_PRINT
(
"info"
,(
"SSL_set_cipher_list() returned %d"
,
result
));
DBUG_PRINT
(
"error"
,
(
"failed to set ciphers to use"
));
report_errors
();
my_free
((
void
*
)
ssl_fd
,
MYF
(
0
));
DBUG_RETURN
(
0
);
}
SSL_CTX_set_verify
(
ptr
->
ssl_context
,
verify
,
vio_verify_callback
);
if
(
vio_set_cert_stuff
(
ptr
->
ssl_context
,
cert_file
,
key_file
)
==
-
1
)
if
(
vio_set_cert_stuff
(
ssl_fd
->
ssl_context
,
cert_file
,
key_file
)
)
{
DBUG_PRINT
(
"error"
,
(
"vio_set_cert_stuff failed"
));
report_errors
();
goto
ctor_failure
;
my_free
((
void
*
)
ssl_fd
,
MYF
(
0
));
DBUG_RETURN
(
0
);
}
if
(
SSL_CTX_load_verify_locations
(
ptr
->
ssl_context
,
ca_file
,
ca_path
)
==
0
)
if
(
SSL_CTX_load_verify_locations
(
ssl_fd
->
ssl_context
,
ca_file
,
ca_path
)
==
0
)
{
DBUG_PRINT
(
"warning"
,
(
"SSL_CTX_load_verify_locations failed"
));
if
(
SSL_CTX_set_default_verify_paths
(
ptr
->
ssl_context
)
==
0
)
if
(
SSL_CTX_set_default_verify_paths
(
ssl_fd
->
ssl_context
)
==
0
)
{
DBUG_PRINT
(
"error"
,
(
"SSL_CTX_set_default_verify_paths failed"
));
report_errors
();
goto
ctor_failure
;
my_free
((
void
*
)
ssl_fd
,
MYF
(
0
));
DBUG_RETURN
(
0
);
}
}
}
/* DH stuff */
dh
=
get_dh512
();
SSL_CTX_set_tmp_dh
(
ptr
->
ssl_context
,
dh
);
SSL_CTX_set_tmp_dh
(
ssl_fd
->
ssl_context
,
dh
);
DH_free
(
dh
);
DBUG_RETURN
(
ptr
);
ctor_failure:
DBUG_PRINT
(
"exit"
,
(
"there was an error"
));
my_free
((
gptr
)
ptr
,
MYF
(
0
));
DBUG_RETURN
(
0
);
DBUG_PRINT
(
"exit"
,
(
"OK 1"
));
DBUG_RETURN
(
ssl_fd
);
}
/************************ VioSSLAcceptorFd **********************************/
/*
TODO:
Add option --verify to mysqld to be able to change verification mode
*/
struct
st_VioSSLAcceptorFd
*
new_VioSSLAcceptorFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
cipher
)
/************************ VioSSLConnectorFd **********************************/
struct
st_VioSSLFd
*
new_VioSSLConnectorFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
cipher
)
{
int
verify
=
(
SSL_VERIFY_PEER
|
SSL_VERIFY_CLIENT_ONCE
);
struct
st_VioSSLAcceptorFd
*
ptr
;
int
result
;
DH
*
dh
;
DBUG_ENTER
(
"new_VioSSLAcceptorFd"
);
struct
st_VioSSLFd
*
ssl_fd
;
int
verify
=
SSL_VERIFY_NONE
;
if
(
!
(
ssl_fd
=
new_VioSSLFd
(
key_file
,
cert_file
,
ca_file
,
ca_path
,
cipher
,
TLSv1_client_method
())))
{
return
0
;
}
/* Init the the VioSSLFd as a "connector" ie. the client side */
ptr
=
((
struct
st_VioSSLAcceptorFd
*
)
my_malloc
(
sizeof
(
struct
st_VioSSLAcceptorFd
),
MYF
(
0
)));
ptr
->
ssl_context
=
0
;
ptr
->
ssl_method
=
0
;
/* FIXME: constants!
*/
ptr
->
session_id_context
=
ptr
;
/*
The verify_callback function is used to control the behaviour
when the SSL_VERIFY_PEER flag is set. Here it is SSL_VERIFY_NONE
and thus callback is set to NULL
*/
SSL_CTX_set_verify
(
ssl_fd
->
ssl_context
,
verify
,
NULL
)
;
if
(
!
ssl_algorithms_added
)
{
DBUG_PRINT
(
"info"
,
(
"todo: OpenSSL_add_all_algorithms()"
));
ssl_algorithms_added
=
TRUE
;
SSL_library_init
();
OpenSSL_add_all_algorithms
();
return
ssl_fd
;
}
}
#ifdef __NETWARE__
netware_ssl_init
();
#endif
if
(
!
ssl_error_strings_loaded
)
{
DBUG_PRINT
(
"info"
,
(
"todo: SSL_load_error_strings()"
));
ssl_error_strings_loaded
=
TRUE
;
SSL_load_error_strings
();
}
ptr
->
ssl_method
=
TLSv1_server_method
();
ptr
->
ssl_context
=
SSL_CTX_new
(
ptr
->
ssl_method
);
if
(
ptr
->
ssl_context
==
0
)
{
DBUG_PRINT
(
"error"
,
(
"SSL_CTX_new failed"
));
report_errors
();
goto
ctor_failure
;
}
if
(
cipher
)
/************************ VioSSLAcceptorFd **********************************/
struct
st_VioSSLFd
*
new_VioSSLAcceptorFd
(
const
char
*
key_file
,
const
char
*
cert_file
,
const
char
*
ca_file
,
const
char
*
ca_path
,
const
char
*
cipher
)
{
struct
st_VioSSLFd
*
ssl_fd
;
int
verify
=
SSL_VERIFY_PEER
|
SSL_VERIFY_CLIENT_ONCE
;
if
(
!
(
ssl_fd
=
new_VioSSLFd
(
key_file
,
cert_file
,
ca_file
,
ca_path
,
cipher
,
TLSv1_server_method
())))
{
result
=
SSL_CTX_set_cipher_list
(
ptr
->
ssl_context
,
cipher
);
DBUG_PRINT
(
"info"
,(
"SSL_set_cipher_list() returned %d"
,
result
));
return
0
;
}
/* SSL_CTX_set_quiet_shutdown(ctx,1); */
SSL_CTX_sess_set_cache_size
(
ptr
->
ssl_context
,
128
);
/* Init the the VioSSLFd as a "acceptor" ie. the server side */
/* DH? */
SSL_CTX_set_verify
(
ptr
->
ssl_context
,
verify
,
vio_verify_callback
);
SSL_CTX_set_session_id_context
(
ptr
->
ssl_context
,
(
const
uchar
*
)
&
(
ptr
->
session_id_context
),
sizeof
(
ptr
->
session_id_context
));
/* Set max number of cached sessions, returns the previous size */
SSL_CTX_sess_set_cache_size
(
ssl_fd
->
ssl_context
,
128
);
/*
SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile));
The verify_callback function is used to control the behaviour
when the SSL_VERIFY_PEER flag is set.
*/
if
(
vio_set_cert_stuff
(
ptr
->
ssl_context
,
cert_file
,
key_file
)
==
-
1
)
{
DBUG_PRINT
(
"error"
,
(
"vio_set_cert_stuff failed"
));
report_errors
();
goto
ctor_failure
;
}
if
(
SSL_CTX_load_verify_locations
(
ptr
->
ssl_context
,
ca_file
,
ca_path
)
==
0
)
{
DBUG_PRINT
(
"warning"
,
(
"SSL_CTX_load_verify_locations failed"
));
if
(
SSL_CTX_set_default_verify_paths
(
ptr
->
ssl_context
)
==
0
)
{
DBUG_PRINT
(
"error"
,
(
"SSL_CTX_set_default_verify_paths failed"
));
report_errors
();
goto
ctor_failure
;
}
}
/* DH stuff */
dh
=
get_dh512
();
SSL_CTX_set_tmp_dh
(
ptr
->
ssl_context
,
dh
);
DH_free
(
dh
);
DBUG_RETURN
(
ptr
);
SSL_CTX_set_verify
(
ssl_fd
->
ssl_context
,
verify
,
vio_verify_callback
);
ctor_failure:
DBUG_PRINT
(
"exit"
,
(
"there was an error"
));
my_free
((
gptr
)
ptr
,
MYF
(
0
));
DBUG_RETURN
(
0
);
/*
Set session_id - an identifier for this server session
Use the ssl_fd pointer
*/
SSL_CTX_set_session_id_context
(
ssl_fd
->
ssl_context
,
ssl_fd
,
sizeof
(
ssl_fd
));
return
ssl_fd
;
}
#endif
/* HAVE_OPENSSL */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment