1 /* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 /*
24  * Vio Lite.
25  * Purpose: include file for Vio that will work with C and C++
26  */
27 
28 #ifndef vio_violite_h_
29 #define	vio_violite_h_
30 
31 #include <my_thread.h> /* my_thread_handle */
32 #include <mysql/psi/psi.h>
33 #include <pfs_socket_provider.h>
34 #include <mysql/psi/mysql_socket.h>
35 
36 /* Simple vio interface in C;  The functions are implemented in violite.c */
37 
38 #ifdef	__cplusplus
39 extern "C" {
40 #endif /* __cplusplus */
41 
42 #ifdef HAVE_PSI_INTERFACE
43 void init_vio_psi_keys();
44 #endif
45 
46 #ifdef __cplusplus
47 typedef struct st_vio Vio;
48 #endif /* __cplusplus */
49 
50 enum enum_vio_type
51 {
52   /**
53     Type of the connection is unknown.
54   */
55   NO_VIO_TYPE= 0,
56   /**
57     Used in case of TCP/IP connections.
58   */
59   VIO_TYPE_TCPIP= 1,
60   /**
61     Used for Unix Domain socket connections. Unix only.
62   */
63   VIO_TYPE_SOCKET= 2,
64   /**
65     Used for named pipe connections. Windows only.
66   */
67   VIO_TYPE_NAMEDPIPE= 3,
68   /**
69     Used in case of SSL connections.
70   */
71   VIO_TYPE_SSL= 4,
72   /**
73     Used for shared memory connections. Windows only.
74   */
75   VIO_TYPE_SHARED_MEMORY= 5,
76   /**
77     Used internally by the prepared statements
78   */
79   VIO_TYPE_LOCAL= 6,
80   /**
81     Implicitly used by plugins that doesn't support any other VIO_TYPE.
82   */
83   VIO_TYPE_PLUGIN= 7,
84 
85   FIRST_VIO_TYPE= VIO_TYPE_TCPIP,
86   /*
87     If a new type is added, please update LAST_VIO_TYPE. In addition, please
88     change get_vio_type_name() in vio/vio.c to return correct name for it.
89   */
90   LAST_VIO_TYPE= VIO_TYPE_PLUGIN
91 };
92 
93 /**
94   Convert a vio type to a printable string.
95   @param vio_type the type
96   @param[out] str the string
97   @param[out] len the string length
98 */
99 void get_vio_type_name(enum enum_vio_type vio_type, const char ** str, int * len);
100 
101 /**
102   VIO I/O events.
103 */
104 enum enum_vio_io_event
105 {
106   VIO_IO_EVENT_READ,
107   VIO_IO_EVENT_WRITE,
108   VIO_IO_EVENT_CONNECT
109 };
110 
111 #define VIO_LOCALHOST 1                         /* a localhost connection */
112 #define VIO_BUFFERED_READ 2                     /* use buffered read */
113 #define VIO_READ_BUFFER_SIZE 16384              /* size of read buffer */
114 #define VIO_DESCRIPTION_SIZE 30                 /* size of description */
115 
116 Vio* vio_new(my_socket sd, enum enum_vio_type type, uint flags);
117 Vio*  mysql_socket_vio_new(MYSQL_SOCKET mysql_socket, enum enum_vio_type type, uint flags);
118 #ifdef _WIN32
119 Vio* vio_new_win32pipe(HANDLE hPipe);
120 Vio* vio_new_win32shared_memory(HANDLE handle_file_map,
121                                 HANDLE handle_map,
122                                 HANDLE event_server_wrote,
123                                 HANDLE event_server_read,
124                                 HANDLE event_client_wrote,
125                                 HANDLE event_client_read,
126                                 HANDLE event_conn_closed);
127 #else
128 #define HANDLE void *
129 #endif /* _WIN32 */
130 
131 void    vio_delete(Vio* vio);
132 int vio_shutdown(Vio* vio);
133 my_bool vio_reset(Vio* vio, enum enum_vio_type type,
134                   my_socket sd, void *ssl, uint flags);
135 size_t  vio_read(Vio *vio, uchar *	buf, size_t size);
136 size_t  vio_read_buff(Vio *vio, uchar * buf, size_t size);
137 size_t  vio_write(Vio *vio, const uchar * buf, size_t size);
138 /* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible */
139 int vio_fastsend(Vio *vio);
140 /* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible */
141 int vio_keepalive(Vio *vio, my_bool	onoff);
142 /* Whenever we should retry the last read/write operation. */
143 my_bool vio_should_retry(Vio *vio);
144 /* Check that operation was timed out */
145 my_bool vio_was_timeout(Vio *vio);
146 /* Short text description of the socket for those, who are curious.. */
147 const char* vio_description(Vio *vio);
148 /* Return the type of the connection */
149 enum enum_vio_type vio_type(Vio* vio);
150 /* Return last error number */
151 int	vio_errno(Vio*vio);
152 /* Get socket number */
153 my_socket vio_fd(Vio*vio);
154 /* Remote peer's address and name in text form */
155 my_bool vio_peer_addr(Vio *vio, char *buf, uint16 *port, size_t buflen);
156 /* Wait for an I/O event notification. */
157 int vio_io_wait(Vio *vio, enum enum_vio_io_event event, int timeout);
158 my_bool vio_is_connected(Vio *vio);
159 #ifndef DBUG_OFF
160 ssize_t vio_pending(Vio *vio);
161 #endif
162 /* Set timeout for a network operation. */
163 int vio_timeout(Vio *vio, uint which, int timeout_sec);
164 /* Connect to a peer. */
165 my_bool vio_socket_connect(Vio *vio, struct sockaddr *addr, socklen_t len,
166                            int timeout);
167 
168 my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, size_t addr_length,
169                                      char *ip_string, size_t ip_string_size);
170 
171 my_bool vio_is_no_name_error(int err_code);
172 
173 int vio_getnameinfo(const struct sockaddr *sa,
174                     char *hostname, size_t hostname_size,
175                     char *port, size_t port_size,
176                     int flags);
177 
178 #ifdef HAVE_OPENSSL
179 #include <openssl/opensslv.h>
180 #if OPENSSL_VERSION_NUMBER < 0x0090700f
181 #define DES_cblock des_cblock
182 #define DES_key_schedule des_key_schedule
183 #define DES_set_key_unchecked(k,ks) des_set_key_unchecked((k),*(ks))
184 #define DES_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e) des_ede3_cbc_encrypt((i),(o),(l),*(k1),*(k2),*(k3),(iv),(e))
185 #endif
186 /* apple deprecated openssl in MacOSX Lion */
187 #ifdef __APPLE__
188 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
189 #endif
190 
191 #include <openssl/ssl.h>
192 #include <openssl/err.h>
193 
194 #if !defined(EMBEDDED_LIBRARY) || defined(XTRABACKUP)
195 enum enum_ssl_init_error
196 {
197   SSL_INITERR_NOERROR= 0, SSL_INITERR_CERT, SSL_INITERR_KEY,
198   SSL_INITERR_NOMATCH, SSL_INITERR_BAD_PATHS, SSL_INITERR_CIPHERS,
199   SSL_INITERR_MEMFAIL, SSL_INITERR_NO_USABLE_CTX, SSL_INITERR_DHFAIL,
200   SSL_TLS_VERSION_INVALID, SSL_INITERR_LASTERR
201 };
202 const char* sslGetErrString(enum enum_ssl_init_error err);
203 
204 struct st_VioSSLFd
205 {
206   SSL_CTX *ssl_context;
207 };
208 
209 int sslaccept(struct st_VioSSLFd*, Vio *, long timeout, unsigned long *errptr);
210 int sslconnect(struct st_VioSSLFd*, Vio *, long timeout, unsigned long *errptr);
211 
212 struct st_VioSSLFd
213 *new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
214                        const char *ca_file,  const char *ca_path,
215                        const char *cipher, enum enum_ssl_init_error *error,
216                        const char *crl_file, const char *crl_path, const long ssl_ctx_flags);
217 
218 long process_tls_version(const char *tls_version);
219 
220 struct st_VioSSLFd
221 *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
222                       const char *ca_file,const char *ca_path,
223                       const char *cipher, enum enum_ssl_init_error *error,
224                       const char *crl_file, const char *crl_path, const long ssl_ctx_flags);
225 void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd);
226 
227 void vio_ssl_end();
228 
229 #endif /* ! EMBEDDED_LIBRARY) || XTRABACKUP */
230 #endif /* HAVE_OPENSSL */
231 
232 void ssl_start(void);
233 void vio_end(void);
234 
235 #ifdef  __cplusplus
236 }
237 #endif
238 
239 #if !defined(DONT_MAP_VIO)
240 #define vio_delete(vio)                         (vio)->viodelete(vio)
241 #define vio_errno(vio)                          (vio)->vioerrno(vio)
242 #define vio_read(vio, buf, size)                ((vio)->read)(vio,buf,size)
243 #define vio_write(vio, buf, size)               ((vio)->write)(vio, buf, size)
244 #define vio_fastsend(vio)                       (vio)->fastsend(vio)
245 #define vio_keepalive(vio, set_keep_alive)  (vio)->viokeepalive(vio, set_keep_alive)
246 #define vio_should_retry(vio)                   (vio)->should_retry(vio)
247 #define vio_was_timeout(vio)                    (vio)->was_timeout(vio)
248 #define vio_shutdown(vio)                       ((vio)->vioshutdown)(vio)
249 #define vio_peer_addr(vio, buf, prt, buflen)    (vio)->peer_addr(vio, buf, prt, buflen)
250 #define vio_io_wait(vio, event, timeout)        (vio)->io_wait(vio, event, timeout)
251 #define vio_is_connected(vio)                   (vio)->is_connected(vio)
252 #endif /* !defined(DONT_MAP_VIO) */
253 
254 /* This enumerator is used in parser - should be always visible */
255 enum SSL_type
256 {
257   SSL_TYPE_NOT_SPECIFIED= -1,
258   SSL_TYPE_NONE,
259   SSL_TYPE_ANY,
260   SSL_TYPE_X509,
261   SSL_TYPE_SPECIFIED
262 };
263 
264 
265 /* HFTODO - hide this if we don't want client in embedded server */
266 /* This structure is for every connection on both sides */
267 struct st_vio
268 {
269   MYSQL_SOCKET  mysql_socket;           /* Instrumented socket */
270   my_bool       localhost;              /* Are we from localhost? */
271   struct sockaddr_storage   local;      /* Local internet address */
272   struct sockaddr_storage   remote;     /* Remote internet address */
273   size_t addrLen;                       /* Length of remote address */
274   enum enum_vio_type    type;           /* Type of connection */
275   my_bool               inactive; /* Connection inactive (has been shutdown) */
276   char                  desc[VIO_DESCRIPTION_SIZE]; /* Description string. This
277                                                       member MUST NOT be
278                                                       used directly, but only
279                                                       via function
280                                                       "vio_description" */
281   char                  *read_buffer;   /* buffer for vio_read_buff */
282   char                  *read_pos;      /* start of unfetched data in the
283                                            read buffer */
284   char                  *read_end;      /* end of unfetched data */
285   int                   read_timeout;   /* Timeout value (ms) for read ops. */
286   int                   write_timeout;  /* Timeout value (ms) for write ops. */
287 
288   /*
289      VIO vtable interface to be implemented by VIO's like SSL, Socket,
290      Named Pipe, etc.
291   */
292 
293   /*
294      viodelete is responsible for cleaning up the VIO object by freeing
295      internal buffers, closing descriptors, handles.
296   */
297   void    (*viodelete)(Vio*);
298   int     (*vioerrno)(Vio*);
299   size_t  (*read)(Vio*, uchar *, size_t);
300   size_t  (*write)(Vio*, const uchar *, size_t);
301   int     (*timeout)(Vio*, uint, my_bool);
302   int     (*viokeepalive)(Vio*, my_bool);
303   int     (*fastsend)(Vio*);
304   my_bool (*peer_addr)(Vio*, char *, uint16*, size_t);
305   void    (*in_addr)(Vio*, struct sockaddr_storage*);
306   my_bool (*should_retry)(Vio*);
307   my_bool (*was_timeout)(Vio*);
308   /*
309      vioshutdown is resposnible to shutdown/close the channel, so that no
310      further communications can take place, however any related buffers,
311      descriptors, handles can remain valid after a shutdown.
312   */
313   int     (*vioshutdown)(Vio*);
314   my_bool (*is_connected)(Vio*);
315   my_bool (*has_data) (Vio*);
316   int (*io_wait)(Vio*, enum enum_vio_io_event, int);
317   my_bool (*connect)(Vio*, struct sockaddr *, socklen_t, int);
318 #ifdef _WIN32
319   OVERLAPPED overlapped;
320   HANDLE hPipe;
321 #endif
322 #ifdef HAVE_OPENSSL
323   void    *ssl_arg;
324 #endif
325 #if defined (_WIN32) && !defined (EMBEDDED_LIBRARY)
326   HANDLE  handle_file_map;
327   char    *handle_map;
328   HANDLE  event_server_wrote;
329   HANDLE  event_server_read;
330   HANDLE  event_client_wrote;
331   HANDLE  event_client_read;
332   HANDLE  event_conn_closed;
333   size_t  shared_memory_remain;
334   char    *shared_memory_pos;
335 #endif /* _WIN32 && !EMBEDDED_LIBRARY */
336 };
337 
338 #ifdef HAVE_OPENSSL
339 #define SSL_handle SSL*
340 #else
341 #define SSL_handle void*
342 #endif
343 
344 #endif /* vio_violite_h_ */
345