1
/* Copyright (C) 2000 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
17
Note that we can't have assertion on file descriptors; The reason for
18
this is that during mysql shutdown, another thread can close a file
19
we are working on. In this case we should just return read errors from
29
/* yaSSL already uses BSD sockets */
33
The default OpenSSL implementation on NetWare uses WinSock.
34
This code allows us to use the BSD sockets.
37
static int SSL_set_fd_bsd(SSL *s, int fd)
40
BIO_METHOD *BIO_s_bsdsocket();
43
if ((bio= BIO_new(BIO_s_bsdsocket())))
45
result= BIO_set_fd(bio, fd, BIO_NOCLOSE);
46
SSL_set_bio(s, bio, bio);
51
#define SSL_set_fd(A, B) SSL_set_fd_bsd((A), (B))
53
#endif /* HAVE_YASSL */
54
#endif /* __NETWARE__ */
58
report_errors(SSL* ssl)
68
DBUG_ENTER("report_errors");
70
while ((l= ERR_get_error_line_data(&file,&line,&data,&flags)))
72
DBUG_PRINT("error", ("OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
73
file,line,(flags&ERR_TXT_STRING)?data:"")) ;
77
DBUG_PRINT("error", ("error: %s",
78
ERR_error_string(SSL_get_error(ssl, l), buf)));
80
DBUG_PRINT("info", ("socket_errno: %d", socket_errno));
85
size_t vio_ssl_read(Vio *vio, uchar* buf, size_t size)
88
DBUG_ENTER("vio_ssl_read");
89
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u ssl: 0x%lx",
90
vio->sd, (long) buf, (uint) size, (long) vio->ssl_arg));
92
r= SSL_read((SSL*) vio->ssl_arg, buf, size);
95
report_errors((SSL*) vio->ssl_arg);
97
DBUG_PRINT("exit", ("%u", (uint) r));
102
size_t vio_ssl_write(Vio *vio, const uchar* buf, size_t size)
105
DBUG_ENTER("vio_ssl_write");
106
DBUG_PRINT("enter", ("sd: %d buf: 0x%lx size: %u", vio->sd,
107
(long) buf, (uint) size));
109
r= SSL_write((SSL*) vio->ssl_arg, buf, size);
111
if (r == (size_t) -1)
112
report_errors((SSL*) vio->ssl_arg);
114
DBUG_PRINT("exit", ("%u", (uint) r));
119
int vio_ssl_close(Vio *vio)
122
SSL *ssl= (SSL*)vio->ssl_arg;
123
DBUG_ENTER("vio_ssl_close");
128
THE SSL standard says that SSL sockets must send and receive a close_notify
129
alert on socket shutdown to avoid truncation attacks. However, this can
130
cause problems since we often hold a lock during shutdown and this IO can
131
take an unbounded amount of time to complete. Since our packets are self
132
describing with length, we aren't vunerable to these attacks. Therefore,
133
we just shutdown by closing the socket (quiet shutdown).
135
SSL_set_quiet_shutdown(ssl, 1);
137
switch ((r= SSL_shutdown(ssl))) {
139
/* Shutdown successful */
143
Shutdown not yet finished - since the socket is going to
144
be closed there is no need to call SSL_shutdown() a second
145
time to wait for the other side to respond
148
default: /* Shutdown failed */
149
DBUG_PRINT("vio_error", ("SSL_shutdown() failed, error: %d",
150
SSL_get_error(ssl, r)));
154
DBUG_RETURN(vio_close(vio));
158
void vio_ssl_delete(Vio *vio)
161
return; /* It must be safe to delete null pointer */
163
if (vio->type == VIO_TYPE_SSL)
164
vio_ssl_close(vio); /* Still open, close connection first */
168
SSL_free((SSL*) vio->ssl_arg);
176
static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
177
int (*connect_accept_func)(SSL*))
181
my_bool was_blocking;
183
DBUG_ENTER("ssl_do");
184
DBUG_PRINT("enter", ("ptr: 0x%lx, sd: %d ctx: 0x%lx",
185
(long) ptr, vio->sd, (long) ptr->ssl_context));
187
/* Set socket to blocking if not already set */
188
vio_blocking(vio, 1, &was_blocking);
190
if (!(ssl= SSL_new(ptr->ssl_context)))
192
DBUG_PRINT("error", ("SSL_new failure"));
194
vio_blocking(vio, was_blocking, &unused);
197
DBUG_PRINT("info", ("ssl: 0x%lx timeout: %ld", (long) ssl, timeout));
199
SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
200
SSL_set_fd(ssl, vio->sd);
202
if (connect_accept_func(ssl) < 1)
204
DBUG_PRINT("error", ("SSL_connect/accept failure"));
207
vio_blocking(vio, was_blocking, &unused);
212
Connection succeeded. Install new function handlers,
213
change type, set sd to the fd used when connecting
214
and set pointer to the SSL structure
216
vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), 0, 0);
217
vio->ssl_arg= (void*)ssl;
221
/* Print some info about the peer */
225
DBUG_PRINT("info",("SSL connection succeeded"));
226
DBUG_PRINT("info",("Using cipher: '%s'" , SSL_get_cipher_name(ssl)));
228
if ((cert= SSL_get_peer_certificate (ssl)))
230
DBUG_PRINT("info",("Peer certificate:"));
231
X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
232
DBUG_PRINT("info",("\t subject: '%s'", buf));
233
X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
234
DBUG_PRINT("info",("\t issuer: '%s'", buf));
238
DBUG_PRINT("info",("Peer does not have certificate."));
240
if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
242
DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
245
DBUG_PRINT("info",("no shared ciphers!"));
253
int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
255
DBUG_ENTER("sslaccept");
256
DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept));
260
int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout)
262
DBUG_ENTER("sslconnect");
263
DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect));
267
int vio_ssl_blocking(Vio *vio __attribute__((unused)),
268
my_bool set_blocking_mode,
271
/* Mode is always blocking */
273
/* Return error if we try to change to non_blocking mode */
274
return (set_blocking_mode ? 0 : 1);
279
#endif /* HAVE_OPENSSL */