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